去年作大實驗初次接觸了裝飾器模式,當時也是懵懵懂懂過去了,沒有太搞明白。最近學習的時候又接觸了裝飾器模式,同時又有了一些新的理解。app
咱們會用到框架自帶的已經封裝好的方法,這節省了咱們寫不少原生方法的時間,可是這些封裝好的代碼可能又不是十分符合咱們所須要的,咱們須要對此進行一些修改。就如同它的名字,咱們須要對封裝好的代碼進行一下「裝飾」。
咱們本着對對修改關閉,對擴展開放的原則,對代碼進行修改。在這裏我舉個例子。
原來有一家生產並在本地零售玻璃杯的廠家,有一天來了一個商人說要訂購大量玻璃杯並運輸到外地去賣,他但願廠家能夠吧生產的玻璃杯用泡沫板包裝好以即可以運輸。這是廠家特地開闢了一條生產線去給杯子包裹泡沫板,這時商家滿意了。
商家想要買杯子,可是如今生產的杯子沒有徹底獲得他的滿意,因而廠家在不改變原來生產線的狀況下,添加了新的生產線,來知足客戶需求。客戶獲得的仍是杯子,可是是被裝飾過的杯子。這就是咱們的裝飾器模式。框架
仍是那教程中例子來講明dom
class Request { String getHeader(String key) { // 獲取header值的真實代碼略 } } class TokenFilterTest { /**在此傳入auth-token的值*/ @Test void doFilter() { String authToken = "654321"; Request request = new Request(); this.getAuthUser(request); } /** 在此獲取auth-token的值 */ void getAuthUser(Request request) { // 獲取auth-token request.getHeader("auth-token"); // 根據auth-token獲取當前登陸用戶 } }
假設框架已經封裝好了Request類和類裏的getHeader方法,咱們在TokenFilterTest類裏須要調用getHeader方法,可是getHeader方法是框架爲咱們封裝好的,咱們不能改變他的代碼,可是現有的方法又打不到咱們如今的需求,咱們就爲他創建一個新的類,可是必定要繼承咱們原來的類。ide
class RequestWrapper extends Request { Request request; private RequestWrapper() { } public RequestWrapper(Request request) { this.request = request; } @Override String getHeader(String key) { return this.request.getHeader(key); } }
咱們經過繼承Request類是能夠調用getHeader方法的,可是咱們的目的是在這個方法的基礎上進行改造,函數
class RequestWrapper extends Request { ... @Override String getHeader(String key) { if ("auth-token".equals(key)) { // 在此返回新的auth-token值 return "456789"; } return this.request.getHeader(key); } }
這樣一個新的方法就寫好了,咱們如今去調用這個方法學習
public class TokenFilterTest { @Test public void doFilter() { String authToken = new RandomString(6).nextString(); System.out.println("authToken傳入值爲" + authToken); Request request = new Request(); RequestWrapper requestWrapper = new RequestWrapper(request, authToken); this.getAuthUser(requestWrapper); } /** 在此獲取auth-token的值 */ void getAuthUser(Request request) { // 獲取auth-token System.out.println("獲取到的auth-token值爲:" + request.getHeader("auth-token")); // 根據auth-token獲取當前登陸用戶 } }
咱們發現咱們在getAuthUser方法並無改變他傳入的參數類型,可是咱們在調用他的時候已經由傳入request變成requestWrapper,說明咱們並無改變他的類型,可是咱們確實是用的RequestWrapper構造函數獲取到的。
原來咱們三個方法的關係是這樣的.
如今咱們對他裝飾一下。咱們發現咱們並無改變getAuthUser。也不用改變getHeader,由於咱們的RequestWrapper類繼承了Request類。this
對於裝飾器模式已經有不少次接觸了,每次接觸都會帶來新的理解,也會帶來提升。spa