В Snap Framework, Snaplets используются для встраивания функциональности в другие Snaplets через компонентный интерфейс: Основное веб-приложение представляет собой Snaplet, который ссылается на другие Snaplets с помощью классического отношения «has-a» , и суб-Snaplets могут, в свою очередь, ссылаться на другие Snaplets.Предпочтительный метод для привязки суб-привязок
При просмотре различных реализаций Snaplet я видел различные шаблоны, используемые для встраивания Snaplet в родительский Snaplet. В частности:
Вид ссылки. Реализация Snaplet предполагает, что существует определенный вид отношения к родительскому Snaplet. Это применяется с использованием метода Reference (см. Ниже).
Простая ссылка:
data MySnaplet = MySnaplet { subSnaplet :: Snaplet SubSnaplet }
Относительный линзы:
data MySnaplet = MySnaplet { _subSnaplet :: Snaplet SubSnaplet } subSnaplet :: Lens MySnaplet SubSnaplet subSnaplet = lens _subSnaplet $ \ a b -> a { _subSnaplet = b }
Контрольный метод. Реализация Snaplet обеспечивает через свой интерфейс конкретный способ доступа к данным Snaplet, а различные реализации Snaplet используют разные методы. Snaplet предполагает, что:
- Данные присутствуют в
MonadState
каждый раз, когда вызывается функция, управляющая Snaplet. - Данные представлены в
MonadState
и завернуты в оберткуSnaplet
. - Существует класс + экземпляр как
instance HasSubSnaplet MySnaplet
, который имеет функцию для получения данных Snaplet выхода изMySnaplet
при условии, чтоMySnaplet
находится вMonadState
в точке вызова функции. - Функция в 3. имеет тип
MySnaplet -> Snaplet SubSnaplet
вместо. - Существует экземпляр класса +, например, в 3., который предоставляет
Lens MySnaplet (Snaplet SubSnaplet)
. - Для экземпляра класса + требуется
Lens (Snaplet MySnaplet) (Snaplet SubSnaplet)
. - Класс + экземпляр предполагает, что
MySnaplet
является «сверху Snaplet» приложения, и требует абсолютного объектива/ссылка, таким образом, чтоMySnaplet
должен быть вMonadSnaplet
b
.
- Данные присутствуют в
Как я это вижу, ссылка вид 1. имеет смысл, если Snaplet только для чтения, и 2. имеет смысл, если Snaplet необходимо изменить.
Кроме того, имея класс для метода имеет смысл, когда MySnaplet
может иметь только один SubSnaplet
и не более, и с абсолютной ссылка может иметь смысл для таких вещей, как базы данных, что не может быть настроена в качестве компонента, учитывая, что только верхний Snaplet имеет доступ к учетным данным, а что нет. Однако принятие этого предположения как писателя Snaplet может быть ошибочным, и вместо этого не было бы никаких недостатков в использовании относительных ссылок.
Существует один прогмм: Существующие привязки к Hackage не соответствуют этим предположениям, которые я делаю; все описанные выше методы используются, по-видимому, случайным образом и при любых обстоятельствах. Кроме того, я не вижу преимуществ/недостатков для некоторых других аспектов, описанных выше (таких как требование обертки Snaplet
, или нет).
Для меня, ссылочный вид 2. и один из методов 1, 2, 5 или 6, кажется, имеют наибольший смысл под всех обстоятельств, и я не вижу причин, по которым не существует консенсуса только с использованием, например, (2, 1) все время.
Итак:
Как писатель Snaplet, какой метод должен быть предпочтительным при написании нового Snaplet (при условии, что он имеет общее назначение), и
Что является причиной, почему все Snaplets в существовании еще не используется один и тот же ссылочный метод (даже в ядре snap
пакет используется тонна различных методов)?
Я не знаком с Snap, но 'StateMonad' должен быть [' MonadState'] (http://hackage.haskell.org/packages/archive/mtl/2.0.1.0/doc/html/Control -Monad-State-Class.html)? – ehird
@ehird right, я слишком привык говорить «Монада государства» – dflemstr
Я не совсем уверен, что вы имеете в виду, когда говорите «тонна различных методов». Мы использовали любой метод, наиболее подходящий для ситуации. – mightybyte