在Snap Framework中,Snaplets用於通過基於組件的接口將功能嵌入到其他Snaplets中:主Web應用程序是一個Snaplet,通過經典的「has-a」關係引用其他Snaplet ,而子Snaplets可以參考其他Snaplets。引用子Snaplets的首選方法
在研究各種Snaplet實現時,我看到了使用不同的模式將Snaplet嵌入到父Snaplet中。具體來說:
參考的種類。 Snaplet實現假定存在與父Snaplet的特定類型的關係。這是通過參考方法強制使用(見下文)。
平紋參考:
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假定:
- 每次調用操作Snaplet的函數時,數據都存在於
MonadState
中。 - 數據存在於
MonadState
中,幷包裹在Snaplet
包裝中。 - 有一個+
instance HasSubSnaplet MySnaplet
類的實例,它具有從MySnaplet
中獲取Snaplet數據的功能,前提是MySnaplet
在調用該函數時位於MonadState
中。 - 3.中的函數代替了
MySnaplet -> Snaplet SubSnaplet
。 - 在3.中有一個類+實例,它提供了一個
Lens MySnaplet (Snaplet SubSnaplet)
。 - 類+實例需要
Lens (Snaplet MySnaplet) (Snaplet SubSnaplet)
。 - 類+實例假設
MySnaplet
是應用程序的「最高Snaplet」,並且需要絕對鏡頭/參考,因此MySnaplet
必須是b
中的MonadSnaplet
。
- 每次調用操作Snaplet的函數時,數據都存在於
在我看來,那種參考1.有道理的,如果在Snaplet是隻讀的,和2有道理,如果Snaplet需要改變。
此外,具有用於該方法的類有意義時MySnaplet
只能有一個SubSnaplet
並沒有更多,和具有絕對基準可能是有意義的事情等的數據庫,其不可能被配置作爲一個組件,因爲只頂級的Snaplet可以訪問憑據,而不是。但是,將這個假設作爲Snaplet作者可能是錯誤的,並且使用相對引用不會有什麼不利。
雖然有一個proglem:Hackage上的現有Snaplets不符合我所做的這些假設;上面描述的所有方法看起來都是隨機的,在各種情況下都可以使用。另外,我認爲上述其他方面沒有優勢/劣勢(例如需要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國家-Class.html)? – ehird 2012-01-13 15:15:56
@ehird對,我太習慣說「The State' monad」 – dflemstr 2012-01-13 15:27:58
我不確定你說的「一噸不同的方法是什麼」。我們使用了最適合這種情況的任何方法。 – mightybyte 2012-01-20 21:43:56