初識裝飾器模式

前言

這一週開局不是很美好,折騰環境折騰了兩天,好在最後都折騰好了,問題的根本不在於電腦,在於窮,自此下定決心,等本身工做掙錢了必定買一臺好電腦。
IMG_20200222_124535.jpg
後來就跟着教程繼續跟進,感受除了單元測試,其餘的都還好吧,不過天天晚上聽潘老師講解一下單元測試,發現單元測試也不是那麼難理解,看到裝飾器模式這部分的介紹有點懵了就:spring

alphago前幾年風靡全球,但你必定想不到的是:早上18世紀晚期的1770年,土耳其便已經擁有了一臺自動下棋(應該是國際象棋)裝置,比2016年3月alphago成名足足早了240年!該下棋裝置在當時擊敗了大多數挑戰者,這其中還包括了拿破崙。此裝置不止可以計算出下一個落棋點,並且還能夠自動拿着棋子下棋,甚至於還會與人交流說"將軍"。
重點就在下棋裝置裏面的"人",實際上在下棋裝置中偷偷藏了一個下棋的高手。而下棋裝置走的每一步棋,都是由該下棋高手在內容操做的(固然這種操做自己使用機器裝置傳遞到機器臂也很複雜)。

但筆者想說的是:這種在下棋裝置中將下棋高手包裝(裝飾)起來,以使得下棋傀儡擁有下棋高手的下棋能力的模式,被稱爲"裝飾器模式"。app

一開始就挺疑惑的,畢竟作出來的東西是人在操控,而且實現的就是人會的下棋功能,這不就是糊弄人嗎,作它的意義是什麼呢,直接讓人下棋不更好嗎,經過後來的代碼,我才知道,所謂的「下棋傀儡」僅僅擁有下棋高手的功能,只是對下棋高手進行了裝飾。ide

應用場景

token的問題解決後本節展現如何將新令牌添加到請求的header中。

上節中學習過了使用request.getHeader(String key);來獲取header中某個key的值。一般來講則還會有個相似的request.setHeader(String key, String value);的方法用於設置header中的某個key的值。單元測試

很遺憾,出於某些方面的考慮spring中(確認說是servlet)中並無提供設置header的方法。學習

在這一節的功能是設置header中的某個key值。
下面用代碼解釋一下具體的做用:測試

class TokenFilterTest 
{
    /**在此傳入auth-token的值*/
    @Test
    void doFilter(HttpServletRequest request)
    {
        String authToken = "654321";
        this.getAuthUser(request);
    }
    /** 在此獲取auth-token的值 */
    void getAuthUser(HttpServletRequest request
    {
        // 獲取auth-token
        request.getHeader("auth-token");
        // 獲取當前登陸用戶header中的auth-token
    }
 }

此處的getHeader()方法爲HttpServletRequest內置的方法,用於獲取header中的某個key值,假如使用裝飾器模式:this

class TokenFilterTest {
...
}

/**
 * HttpServletRequest傀儡
 */
 /*繼承自HttpServletRequest,那麼該傀儡擁有HttpServletRequest 的全部方法*/
class RequestWrapper extends HttpServletRequest 
{
 /*必須裝入一個真正的HttpServletRequest */
    HttpServletRequest request; 
   
    private RequestWrapper()
    { 
    }
    /*必須裝入一個真正的HttpServletRequest */
    public RequestWrapper(HttpServletRequest request) 
    { 
        this.request = request;
    }

    @Override
    /*擁有HttpServletRequest的getHeader()功能*/
    String getHeader(String key)
    { 
    /*實際完成getHeader()功能的是真正的HttpServletRequest */
        return this.request.getHeader(key); 
    }
}

那麼上面的方法就變成了這樣:spa

class TokenFilterTest 
{
    /**在此傳入auth-token的值*/
    @Test
    void doFilter(HttpServletRequest request)
    {
        String authToken = "654321";
        RequestWrapper requestWrapper = new RequestWrapper(request);        
        this.getAuthUser(requestWrapper);
     }
    /** 在此獲取auth-token的值 */
    void getAuthUser(HttpServletRequest request
    {
        // 獲取auth-token
        request.getHeader("auth-token");
        // 獲取當前登陸用戶header中的auth-token
    }
 }
 /**
 * HttpServletRequest傀儡
 */
 /*繼承自HttpServletRequest,那麼該傀儡擁有HttpServletRequest 的全部方法*/
class RequestWrapper extends HttpServletRequest 
{
 /*必須裝入一個真正的HttpServletRequest */
    HttpServletRequest request; 
   
    private RequestWrapper()
    { 
    }
    /*必須裝入一個真正的HttpServletRequest */
    public RequestWrapper(HttpServletRequest request) 
    { 
        this.request = request;
    }

    @Override
    /*擁有HttpServletRequest的getHeader()功能*/
    String getHeader(String key)
    { 
    /*實際完成getHeader()功能的是真正的HttpServletRequest */
        return this.request.getHeader(key); 
    }
}

那麼這時候我即可以對header中的某個key值進行賦值操做:code

/**
 * Request傀儡
 */
class RequestWrapper extends HttpServletRequest {
    ...
    @Override
    String getHeader(String key) {
        if ("auth-token".equals(key)) {
            // 在此返回新的auth-token值
            return "456789";
        }
        return this.request.getHeader(key);
    }
}

要想返回特定的auth—token值,只需用某一變量進行傳值便可,這裏也就不作詳細配置了。blog

總結

因爲剛剛開始這部分的學習,不瞭解這樣作對後面有什麼影響,可是值得高興的是,爲之後相似問題的解決提供了新的思想,之後要學的還不少,這也許只是個開始吧。最後呢,但願疫情早點過去,不但願再有壞消息了。

相關文章
相關標籤/搜索