設計模式,就這麼回事——訪客模式

需求:優酷要求設計一個不同用戶可以觀看不同類別的視頻資源的系統,這應該要用訪客模式吧。
分析1:
一上來,先來個小學生的分析思維:得有不同的用戶類,比如 普通用戶 , 黃金用戶 , 鑽石用戶 , 視頻資源有 普通視頻 , 黃金視頻 , 鑽石視頻 。(鑽石視頻就是說鑽石用戶可看)對於不同的用戶,展開鑑權。好了,開工:

class 用戶()
{   看視頻(視頻)     }

class 普通用戶()
{
    看視頻( 視頻 ){
        if 視頻 == 普通視頻 可以看;
        if 視頻 == 黃金、鑽石  不可以看;
    }
}
class 黃金用戶()
{
    看視頻( 視頻 ){
        if 視頻 == 普通 黃金視頻 可以看;
        if 視頻 == 鑽石  不可以看;
    }
}
class 鑽石用戶()
{
    看視頻( 視頻 ){
        管你什麼視頻 都可以看;
    }
}

當然還有一些視頻類:
class 普通視頻,黃金視頻,鑽石視頻;

//這樣使用:
小明 = 普通用戶()
視頻 = 普通視頻()
小明.看視頻( 視頻 )    OK
視頻 = 黃金視頻()
小明.看視頻( 視頻 )    NO

完工!感覺還可以。這算訪客模式嗎?當然不算!
優酷老總提要求了,說是要增加一檔特別節目,比如成人節目,只允許 紅寶石用戶 觀看,看看怎麼修改代碼:臥槽,代碼全要改動:
首先要增加一個 成人節目 類;還要增加一個 紅寶石用戶 類 ;這些不說,坑爹的是所有之前的鑑權代碼都要改,對於每一個用戶 , 都要對 所有 視頻進行遍歷鑑權;。。。大概如下:

class 成人視頻(){ 。。。 }
class 紅寶石用戶(){ 。。。 }
class 普通用戶()
{
    看視頻(視頻)
    {
        if 視頻 == 普通視頻 可以看;
        if 視頻 == 黃金、鑽石  不可以看;
        //添加的部分
        if 視頻 == 成人視頻 不可以看;
    }
}
其他所有用戶都要這樣改。。。
如果哪天又推新節目,就廢了。。。

評價1:上述方法,符合人的直觀思維,易於理解。不過大量重複,也無封裝、動態可言,實則是面向過程的設計。

分析2:
分析一下系統,特點如下:用戶是變動的,視頻是變動的,用戶要和視頻發生關係。並且視頻的變動大於用戶的變動。這很適合用訪客模式。
這裏主要解決的是 , 如何讓 視頻 的變動不影響用戶的代碼,如何讓 視頻 的變動不影響 用戶 的代碼。
先看第一個,如何讓 視頻 的變動不影響 用戶。之前的系統是做不到這一點的,用戶在 代碼中遍歷了 視頻,視頻改了用戶代碼也得改。其實,如果是用戶 “訪問”視頻 的話,用戶就依賴 視頻,免不了跟着 視頻 改動。何不轉換一下思維方式,讓 視頻 ”訪問“ 用戶——對用戶進行鑑權。這樣,就變成視頻 依賴 用戶,至少可以解決第一個問題,就是 視頻 變化不影響 用戶 了。第二個問題如何解決後面再說。
好了,開工:

class 普通用戶,黃金用戶,鑽石用戶。。。隨便加。。
//重點在下面
class 普通視頻(){
    看視頻( 用戶 )
    if 用戶 在普通之上  可以看;
}
class 黃金視頻(){
    看視頻( 用戶 )
    if 用戶 在黃金之上  可以看;
}
其他類似。
爲了配合視頻 “操作” 用戶的這一特殊功能,我們得把用戶類稍作改動。以普通用戶爲例,其他同。
class 普通用戶(){
    看視頻( 用戶自己 , 視頻 )
    視頻.看視頻( 用戶自己 )
}
//上面是精華:在用戶中,並不需要自己實現鑑權行爲,而是交給 視頻 類去處理,
//爲了讓 視頻 能認識自己,還把自己作爲參數傳了進去,這下視頻端就可以實現對用戶的鑑權了。

那麼怎麼使用呢,像這樣:
小明 = 普通用戶()
視頻 = 普通視頻()
小明.看視頻( 視頻 )  OK~
視頻 = 黃金視頻()
小明.看視頻(視頻)  NO!

//如果哪天添加視頻種類了,只需要這樣即可
視頻 = 成人視頻()
小明.看視頻( 視頻 )
//根本不需要改用戶代碼,所有鑑權操作在 成人視頻 中完成。

到這裏,解決了一大問題,還有一個問題是,如何讓 用戶 的改動不影響 視頻 , 現在 視頻類 中要對 所有 用戶 鑑權,視頻其實是依賴用戶的,對這種依賴的一個應對策略就是 保證用戶類別的穩定性。沒有什麼辦法比這個辦法更好了。
是在不行,再使用如下方法:
在視頻類中,放一份用戶類別列表,這份列表由 用戶工廠 維護。視頻 類需要從 用戶 工廠中 獲取到這個 列表,然後對裏面的用戶 遍歷鑑權。這樣也能做到即使 用戶變化了,視頻 類也無需改動 , 因爲視頻類 內部處理的是 用戶列表,至於有幾個用戶,無關緊要。
大致如下實現視頻類:

class 視頻(){
    用戶列表 = 用戶工廠.get用戶列表()
    for 用戶 in 用戶列表{
        鑑權。。
    }
}

到此,兩大問題都解決了。設計完之後,聰明的你可能會發現,用戶 和 視頻 地位其實是對等的。能用 視頻 訪問 用戶的思路解決問題,其實原來的 用戶 訪問 視頻 也能解決問題。的確如此,用戶訪問視頻模式 ,首先用戶的變化不影響視頻,其次,用一個視頻列表就可以解決視頻的變化不影響用戶。只不過,訪客模式強調的訪客的穩定性,即這裏的用戶是穩定的,如果要設計,就得讓用戶成爲 被訪問 對象。說白了,兩個類發生關係,哪個類穩定,就讓哪個類充當 被處理者。這,就是訪客模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章