生活随笔
收集整理的這篇文章主要介紹了
『设计模式』我能进来坐坐吗?--访问者模式
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
23種設計模式+額外常用設計模式匯總 (持續更新)
訪問者模式
訪問者( Visitor )模式的定義: 將作用于某種數據結構中的各元素的操作分離出來封裝成獨立的類,使其在不改變數據結構的前提下可以添加作用于這些元素的新的操作, 為數據結構中的每個元素提供多種訪問方式。它將對數據的操作與數據結構進行分離,是行為類模式中最復雜的一種模式。
優點:
①擴展性好。能夠在不修改對象結構中的元素的情況下,為對象結構中的元素添加新的功能。
②復用性好。可以通過訪問者來定義整個對象結構通用的功能,從而提高系統的復用程度。
③靈活性好。訪問者模式將數據結構與作用于結構上的操作解囑, 使得操作集合可相對自由地
演化而不影響系統的數據結構。
④符合單一職責原則。訪問者模式把相關的行為封裝在一起,構成一個訪問者,使每一個訪問
者的功能都比較單一。
缺點:
①增加新的元素類很困難。在訪問者模式中,每增加一個新的元素類,都要在每一個具體訪問者類中增加相應的具體操作, 這違背了“開閉原則” 。
②破壞封裝。訪問者模式中具體元素對訪問者公布細節, 這破壞了對象的封裝性。
③違反了依賴倒置原則。訪問者模式依賴了具體類,而沒有依賴抽象類。
使用場景: 1、對象結構中對象對應的類很少改變,但經常需要在此對象結構上定義新的操作。 2、需要對一個對象結構中的對象進行很多不同的并且不相關的操作,而需要避免讓這些操作"污染"這些對象的類,也不希望在增加新操作時修改這些類。
應用場景
對象結構相對穩定,但其操作算法經常變化的程序。
對象結構中的對象需要提供多種不同且不相關的操作,而且要避免讓這些操作的變化影響對象的結構。
對象結構包含很多類型的對象,希望對這些對象實施一些依賴于其具體類型的操作。
實現
模式的結構
訪問者模式包含以下主要角色。
( 1 )抽象訪問者( Visitor )角色: 定義一個訪問具體元素的接口,為每個具體元素類對應一個訪問操作visitXXX() ,該操作中的參數類型標識了被訪問的具體元素。
( 2 ) 具體訪問者( Concrete Visitor )角色: 實現抽象訪問者角色中聲明的各個訪問操作,確定訪問者訪問一個元素時該做什么。
( 3 )抽象元素( Element )角色: 聲明一個包含接受操作accept()的接口,被接受的訪問者對象作為accept()方法的參數。
( 4 )具體元素( Concrete Element )角色:實現抽象元素角色提供的accept()操作,其方法體通常都是visitor.visit(this) ,另外具體元素中可能還包含本身業務邏輯的相關操作。
( 5 )對象結構(Object Structure ) 角色:是一個包含元素角色的容器,提供讓訪問者對象遍歷容器中的所有元素的方法,通常由List、Set、Map 等聚合類實現。
UML:
package Visitor
;import java
.util
.ArrayList
;
import java
.util
.Iterator
;
import java
.util
.List
;interface Visitor {void visit(ConcreteElementA element
);void visit(ConcreteElementB element
);
}
class ConcreteVisitorA implements Visitor {public void visit(ConcreteElementA element
) {System
.out
.println("具體訪問者A訪問-->" + element
.operationA());}public void visit(ConcreteElementB element
) {System
.out
.println("具體訪問者A訪問-->" + element
.operationB());}
}
class ConcreteVisitorB implements Visitor {public void visit(ConcreteElementA element
) {System
.out
.println("具體訪問者B訪問-->" + element
.operationA());}public void visit(ConcreteElementB element
) {System
.out
.println("具體訪問者B訪問-->" + element
.operationB());}
}
interface Element {void accept(Visitor visitor
);
}
class ConcreteElementA implements Element {public void accept(Visitor visitor
) {visitor
.visit(this);}public String
operationA() {return "具體元素A的操作。";}
}
class ConcreteElementB implements Element {public void accept(Visitor visitor
) {visitor
.visit(this);}public String
operationB() {return "具體元素B的操作。";}
}
class ObjectStructure {private List
<Element> list
= new ArrayList<Element>();public void accept(Visitor visitor
) {Iterator
<Element> i
= list
.iterator();while (i
.hasNext()) {((Element
) i
.next()).accept(visitor
);}}public void add(Element element
) {list
.add(element
);}public void remove(Element element
) {list
.remove(element
);}
}public class VisitorTest {public static void main(String
[] args
) {ObjectStructure os
= new ObjectStructure();os
.add(new ConcreteElementA());os
.add(new ConcreteElementB());Visitor visitor
= new ConcreteVisitorA();os
.accept(visitor
);System
.out
.println("------------------------");visitor
= new ConcreteVisitorB();os
.accept(visitor
);}
}
我們再舉一個客戶管理系統的例子
用戶位個人用戶,企業用戶
提出服務申請、客戶價值分析、客戶對產品偏好
package CRM
;public interface Customer {public void accpet(Visitor vis
);}package CRM
;public class Enterprise implements Customer {@Overridepublic void accpet(Visitor vis
) {vis
.visit(this);}public String
oper(){return "企業用戶";}}package CRM
;public class Personal implements Customer {@Overridepublic void accpet(Visitor vis
) {vis
.visit(this);}public String
oper(){return "個人用戶";}}package CRM
;public interface Visitor {public void visit(Enterprise ent
);public void visit(Personal per
);}package CRM
;public class Service_ApplyFor implements Visitor{@Overridepublic void visit(Enterprise ent
) {System
.out
.println(ent
.oper()+"提出企業用戶的服務申請");}@Overridepublic void visit(Personal per
) {System
.out
.println(per
.oper()+"提出個人用戶的服務申請");}}package CRM
;public class Customer_AnalyzePrefer implements Visitor{@Overridepublic void visit(Enterprise ent
) {System
.out
.println("對"+ent
.oper()+"提供企業用戶的客戶產品偏好分析");}@Overridepublic void visit(Personal per
) {System
.out
.println("對"+per
.oper()+"提供個人用戶的客戶產品偏好分析");}}package CRM
;public class Customer_AnalyzeValue implements Visitor{@Overridepublic void visit(Enterprise ent
) {System
.out
.println("對"+ent
.oper()+"提供企業用戶的客戶價值分析");}@Overridepublic void visit(Personal per
) {System
.out
.println("對"+per
.oper()+"提供個人用戶的客戶價值分析");}}package CRM
;import java
.util
.ArrayList
;import java
.util
.List
;public class Manage_System {private List
<Customer> OperList
= new ArrayList<>();public void accept(Visitor vis
) {for (Customer cus
: OperList
) {cus
.accpet(vis
);}}public void add(Customer cus
){OperList
.add(cus
);}public void remove(Customer cus
){OperList
.remove(cus
);}}package CRM
;public class Client {public static void main(String
[] args
) {Manage_System MS
= new Manage_System();MS
.add(new Personal());MS
.add(new Enterprise());Visitor vis
=new Customer_AnalyzePrefer();MS
.accept(vis
);vis
=new Customer_AnalyzeValue();MS
.accept(vis
);vis
=new Service_ApplyFor();MS
.accept(vis
);}}
總結
以上是生活随笔為你收集整理的『设计模式』我能进来坐坐吗?--访问者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。