責任鏈模式,十分常見,好比說,j2ee裏的filter,express裏的middleware,redux裏的middlewarejava
問題是:怎麼才能夠用最簡單的方式實現一個責任鏈模式?
用數組,鏈表來記錄中間件?這些都想過,後來終於找到一種很簡單的方式,靈感來自於fpexpress
對於使用者來講,Middleware應該是不可見的,他們想要的只是最後的結果,也就是一個普通的函數:redux
input => output
因此,先定義一個Function接口來表示:數組
public interface Function { Object apply(Object input); }
這個middleware最後抽象出來的樣子,會決定咱們後面的實現方式
Middleware跟Function的區別在於,Middleware除了能拿到input,它還能拿到"下一站"的Function
因此,middleware應該是一個能對Function進行AOP加強的東西:app
(input, Function) => output
public interface Middleware { Object apply(Object input, Function f); }
最後,咱們要實現一個結合函數:函數
(oldFunction, Middleware) => newFunction
就是說,給你一個oldFunction和一個Middleware,要返回一個newFunction,就是oldFunction經過Middleware加強之後的東西
這個newFunction,能夠直接交給用戶使用,又或者,能夠繼續給它增長Middlewareunix
public static Function combine(final Function f, final Middleware mid) { return new Function() { public Object apply(final Object input) { return mid.apply(input, f); } }; }
能夠看到,input是先流進Middleware的,而後裏面幹什麼,就由這個Middleware決定了。code
這樣子,責任鏈就完成了,20行不到的代碼。中間件
public class Chain { public interface Function { Object apply(Object input); } public interface Middleware { Object apply(Object input, Function f); } public static Function combine(final Function f, final Middleware mid) { return new Function() { public Object apply(final Object input) { return mid.apply(input, f); } }; } }
FP是好東西,去掉了OO裏面那些包裝的概念,思考的時候會更簡單直接。接口
管道模式,也就是unix裏面CLI程序串接起來的模式,對應到fp,其實就是最簡單的函數組合
h(x) | g | f 其實就是 f(g(h(x)))
將責任鏈模式 與 管道模式 對比,會發現,能力上,責任鏈是完勝管道的,由於責任鏈其實是對Function的AOP加強,這種加強,能夠是同時包含了前置的和後置的。
而管道模式的加強,只能是前置的(或者後置的)。
管道模式 : (Function, Function) => Function 責任鏈模式 : (Function, Middleware) => Function