設計模式--訪問者模式

看一個測評系統的需求:將觀眾分為男人和女人,對歌手進行測評,當某個歌手完成表演後,得到他們對該歌手不同的評價(比如成功或者失敗)。傳統方案如下:

傳統方案帶來的問題: 1) ,如果系統比較小,還是比較ok的,但是如果系統比較大,考慮到系統增加越來越多的功能時,對代碼改動比較大違反瞭OCP原則。 2) 擴展性不好,比如說新增人員類型或者管理辦法時,均不好做。==>訪問者模式。訪問這次模式(Visitor Pattern)介紹: 1. 封裝一些作用於某些數據結構的各種元素的操作,它可以在不改變數據結構的前提下定義作用於這些元素的新操作。 2. 主要講數據結構和數據操作分離。解決數據結構和操作耦合性問題。 3. 訪問者模式的基本原理是:在被訪問的類裡面提供一個接待訪問者的接口。 4. 訪問者模式的主要應用場景是:需要對一個結構對象中的對象進行不同的操作(這些操作彼此都沒有關聯),同時要避免這些操作"污染"對象的類,可以選用訪問者模式解決。訪問者模式類圖:

對原理類圖的說明即訪問者模式的角色和職責: 1) Visitor訪問者角色。它是抽象類或者接口,為該對象結構中的ConcreteElement聲明一個visit操作。 2) ConcreteVisitor是具體的訪問者角色,它實現瞭Visitor接口,實現由每個Visitor聲明的操作。 3) ObjectStructured能枚舉他的元素,可以提供一個他的高層接口用來允許訪問者訪問元素。 4) Element定義瞭一個accept方法用來接收一個訪問者對象,它是一個抽象類或者接口 5) ConcreteElement為具體的元素,實現瞭Element接口的accept方法。

訪問者模式解決歌手評分項目: 1) UML類圖:

2) 代碼實現:package com.xia.designmode.study.visitorpattern;import java.util.ArrayList;import java.util.List;/*** * 訪問者模式 數據結構角色,維護瞭很多Persion的action * */public class ObjectStructer { private List<Persion> persionList; public ObjectStructer() { this.persionList = new ArrayList<>(); } /** * 增加一個人的評價 * */ public boolean addPersion(Persion persion){ return persionList.add(persion); } /** * 移出一個人的評價 * */ public boolean removePersion(Persion persion){ return persionList.remove(persion); } /** * 顯示所有人的評價 * */ public void showAll(Action action){ for (Persion persion:persionList) { persion.accept(action); } }}小結:上面提到瞭雙分派機制,所謂雙分派機制是不管類怎麼變化,我們都能找到期望的方法運行。雙分派意味著得到執行的操作取決於請求的種類和兩個接收者的類型。以上面實例為例子,假設我們要添加一個noBat的狀態類,考察man類和woman類的反應,由於使用瞭雙分派機制,隻需要增加一個action類就可以在客戶端調用,不需要改動任何其他的代碼。訪問者模式註意事項和細節: 1. 訪問者模式符合單一職責原則,讓程序具有優秀的擴展性。靈活性非常高。 2. 訪問者模式可以對功能進行統一,可以做報表、UI、攔截器與過濾器,適合用於結構相對穩定的系統。缺點: 1) 具體元素對訪問者公佈細節,也就是說訪問者關註瞭其他類的內部細節,這是迪米特法則所不建議的。這就造成瞭具體元素變更比較困難。 2) 違背瞭依賴倒轉原則,訪問者依賴的是具體元素而不是抽象元素。 3. 如果一個系統有比較穩定的數據結構,又有經常變化的功能,那麼使用訪問者模式還是比較可以的。(本例子中Persion是穩定的,隻有man和woman)。

赞(0)