Java描述設計模式(23):訪問者模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡
一、生活場景
1、場景描述
電競是遊戲比賽達到“競技”層面的體育專案。利用電子裝置作為運動器械進行的、人與人之間的智力對抗運動。通過電競,可以提高人的反應能力、協調能力、團隊精神等。但是不同人群的對電競的持有的觀念不一樣,有的人認為電競就是沉迷網路,持反對態度,而有的人就比較贊同。下面基於訪問者模式來描述該場景。
2、場景圖解
3、程式碼實現
public class C01_InScene { public static void main(String[] args) { DataSet dataSet = new DataSet() ; dataSet.addCrowd(new Youth()); dataSet.addCrowd(new MiddleAge()); CrowdView crowdView = new Against() ; dataSet.display(crowdView); crowdView = new Approve() ; dataSet.display(crowdView); } } /** * 雙分派,不同人群管理 */ abstract class Crowd { abstract void accept(CrowdView action); } class Youth extends Crowd { @Override public void accept(CrowdView view) { view.getYouthView(this); } } class MiddleAge extends Crowd { @Override public void accept(CrowdView view) { view.getMiddleAgeView (this); } } /** * 不同人群觀念的管理 */ abstract class CrowdView { // 青年人觀念 abstract void getYouthView (Youth youth); // 中年人觀念 abstract void getMiddleAgeView (MiddleAge middleAge); } class Approve extends CrowdView { @Override public void getYouthView(Youth youth) { System.out.println("青年人贊同電競"); } @Override public void getMiddleAgeView(MiddleAge middleAge) { System.out.println("中年人贊同電競"); } } class Against extends CrowdView { @Override public void getYouthView(Youth youth) { System.out.println("青年人反對電競"); } @Override public void getMiddleAgeView(MiddleAge middleAge) { System.out.println("中年人反對電競"); } } /** * 提供一個數據集合 */ class DataSet { private List<Crowd> crowdList = new ArrayList<>(); public void addCrowd (Crowd crowd) { crowdList.add(crowd); } public void display(CrowdView crowdView) { for(Crowd crowd : crowdList) { crowd.accept(crowdView); } } }
二、訪問者模式
1、基礎概念
訪問者模式是物件的行為模式,把作用於資料結構的各元素的操作封裝,操作之間沒有關聯。可以在不改變資料結構的前提下定義作用於這些元素的不同的操作。主要將資料結構與資料操作分離,解決資料結構和操作耦合問題核心原理:被訪問的類裡面加對外提供接待訪問者的介面。
2、模式圖解
3、核心角色
- 抽象訪問者角色
宣告多個方法操作,具體訪問者角色需要實現的介面。
- 具體訪問者角色
實現抽象訪問者所宣告的介面,就是各個訪問操作。
- 抽象節點角色
宣告接受操作,接受訪問者物件作為引數。
- 具體節點角色
實現抽象節點所規定的具體操作。
- 結構物件角色
能列舉結構中的所有元素,可以提供一個高層的介面,用來允許訪問者物件訪問每一個元素。
4、原始碼實現
public class C02_Visitor { public static void main(String[] args) { ObjectStructure obs = new ObjectStructure(); obs.add(new NodeA()); obs.add(new NodeB()); Visitor visitor = new VisitorA(); obs.doAccept(visitor); } } /** * 抽象訪問者角色 */ interface Visitor { /** * NodeA的訪問操作 */ void visit(NodeA node); /** * NodeB的訪問操作 */ void visit(NodeB node); } /** * 具體訪問者角色 */ class VisitorA implements Visitor { @Override public void visit(NodeA node) { node.operationA() ; } @Override public void visit(NodeB node) { node.operationB() ; } } class VisitorB implements Visitor { @Override public void visit(NodeA node) { node.operationA() ; } @Override public void visit(NodeB node) { node.operationB() ; } } /** * 抽象節點角色 */ abstract class Node { /** * 接收訪問者 */ abstract void accept(Visitor visitor); } /** * 具體節點角色 */ class NodeA extends Node{ @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationA(){ System.out.println("NodeA.operationA"); } } class NodeB extends Node{ @Override public void accept(Visitor visitor) { visitor.visit(this); } public void operationB(){ System.out.println("NodeB.operationB"); } } /** * 結構物件角色類 */ class ObjectStructure { private List<Node> nodes = new ArrayList<>(); public void detach(Node node) { nodes.remove(node); } public void add(Node node){ nodes.add(node); } public void doAccept(Visitor visitor){ for(Node node : nodes) { node.accept(visitor); } } }
三、Spring框架應用
1、Bean結構的訪問
BeanDefinitionVisitor類,遍歷bean的各個屬性;介面 BeanDefinition,定義Bean的各樣資訊,比如屬性值、構造方法、引數等等。這裡封裝操作bean結構的相關方法,但卻沒有改變bean的結構。
2、核心程式碼塊
public class BeanDefinitionVisitor {
public void visitBeanDefinition(BeanDefinition beanDefinition) {
this.visitParentName(beanDefinition);
this.visitBeanClassName(beanDefinition);
this.visitFactoryBeanName(beanDefinition);
this.visitFactoryMethodName(beanDefinition);
this.visitScope(beanDefinition);
if (beanDefinition.hasPropertyValues()) {
this.visitPropertyValues(beanDefinition.getPropertyValues());
}
if (beanDefinition.hasConstructorArgumentValues()) {
ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
this.visitIndexedArgumentValues(cas.getIndexedArgumentValues());
this.visitGenericArgumentValues(cas.getGenericArgumentValues());
}
}
}
四、模式總結
1、優點描述
(1) 訪問者模式符合單一職責原則、使程式具有良好的擴充套件性、靈活性;
(2) 訪問者模式適用與攔截器與過濾器等常見功能,資料結構相對穩定的場景;
2、缺點描述
(1) 訪問者關注其他類的內部細節,依賴性強,違反迪米特法則,這樣導致具體元素更新麻煩;
(2) 訪問者依賴具體元素,不是抽象元素,面向細節程式設計,違背依賴倒轉原則;
五、原始碼地址
GitHub·地址
https://github.com/cicadasmile/model-arithmetic-parent
GitEE·地址
https://gitee.com/cicadasmile/model-arithmetic-parent
相關推薦
Java描述設計模式(23):訪問者模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、生活場景 1、場景描述 電競是遊戲比賽達到“競技”層面的體育專案。利用電子裝置作為運動器械進行的、人與人之間的智力對抗運動。通過電競,可以提高人的反應能力、協調能力、團隊精神等。但是不同人群的對電競的持有的觀念不一樣,有的人認為電競就是沉迷網路,
23種設計模式(9):訪問者模式(轉)
類方法 打印 interface 增加 http col visitor 設計模式的 接口 定義:封裝某些作用於某種數據結構中各元素的操作,它可以在不改變數據結構的前提下定義作用於這些元素的新的操作。 類型:行為類模式 類圖: 訪問者模式可能是行為類模式中最
23種設計模式(9):訪問者模式
定義:封裝某些作用於某種資料結構中各元素的操作,它可以在不改變資料結構的前提下定義作用於這些元素的新的操作。 型別:行為類模式 類圖: 訪問者模式可能是行為類模式中最複雜的一種模式了,但是這不能成為我們不去掌握它的理由。我們首先來看一個簡單的例子,程式碼如下
Java描述設計模式(02):簡單工廠模式
一、生活場景簡介 1、引入場景 訂餐流程簡單描述 1)、食品抽象類,規定食品的基礎屬性操作 2)、魚類,雞肉類食品類擴充套件 3)
Java描述設計模式(08):橋接模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、橋接模式簡介 1、基礎描述 橋樑模式是物件的結構模式。又稱為柄
Java描述設計模式(09):裝飾模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、生活場景 1、場景描述 孫悟空有七十二般變化,他的每一種變化都
Java描述設計模式(10):組合模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、生活場景 1、檔案系統 下圖是常見的計算機檔案系統的一部分。
Java描述設計模式(11):觀察者模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、觀察者模式 1、概念描述 觀察者模式是物件的行為模式,又叫釋出
Java描述設計模式(13):迭代器模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、迭代器模式 1、基礎概念 迭代器模式又叫遊標模式,是物件的行為
Java描述設計模式(17):調停者模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、生活場景 1、場景描述 在公司的日常安排中,通常劃分多個部門,每個部門又會分為不同的小組,部門經理的一項核心工作就是協調部門小組之間的工作,例如開發小組,產品小組,小組的需求統一彙總到經理,經理統一安排和協調。 2、場景圖解 3、程式碼實
Java描述設計模式(18):享元模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、使用場景 應用程式碼 public class C01_InScene { public static void main(String[] args) { String c0 = "cicada" ; S
Java描述設計模式(19):模板方法模式
本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、生活場景 通常一款網際網路應用的開發流程如下:業務需求,規劃產品,程式開發,測試交付。現在基於模板方法模式進行該過程描述。 public class C01_InScene { public static void main(String
23種設計模式中的訪問者模式
功能需求 封裝 改變 擴展 數據結構 模式 困難 操作 如果 訪問者模式:對於一組對象,在不改變數據結構的前提下,增加作用於這些結構元素新的功能。 適用於數據結構相對穩定,它把數據結構和作用於其上的操作解耦,使得操作集合可以相對自由地演化。 優點: 符合單一職責原則 擴展性
Java設計模式(三) Visitor(訪問者)模式及多分派場景應用
public mod 項目 getname total college hide word dsm 基本概念 Visitor 封裝一些作用於數據結構中的各元素的操作,不同的操作能夠借助新的visitor實現。減少了操作間的耦合性 訪問者能夠將數
23種設計模式[5]:原型模式
exceptio 方法 權限設置 his 但是 單獨 () 實現 條件 定義:用原型實例指定創建對象的種類,並通過拷貝這些原型創建新的對象。 類型:創建類模式 類圖: 原型模式主要用於對象的復制,它的核心是就是類圖中的原型類Prototype。Prototype類
Java進階篇設計模式之十 ---- 訪問者模式和中介者模式
前言 在上一篇中我們學習了結構型模式的直譯器模式(Interpreter Pattern)和迭代器模式(Iterator Pattern)。本篇則來學習下行為型模式的兩個模式,訪問者模式(Visitor Pattern)和中介者模式(Mediator Pattern)。 訪問者模式 簡介 訪問者
Java設計模式10: 策略模式
一、什麼是策略模式? 策略模式屬於物件的行為模式。其用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化。 策略模式把一個系列的演算法封裝到一個系列的具體策略類裡面,作為一個抽象策略類的子類或
Java設計模式8:外觀模式
一、外觀模式的定義: 外觀模式隱藏了系統的複雜性,並向客戶端提供了一個可以訪問系統的介面。這種型別的設計模式屬於結構性模式。為子系統中的一組介面提供了一個統一的訪問介面,這個介面使得子系統更容易被訪問或者使用。 二、外觀模式的結構: 1、外觀角色:外觀模式的核心。它
Java設計模式12:命令模式
一、什麼是命令模式? 在閻巨集博士的《JAVA與模式》一書中開頭是這樣描述命令(Command)模式的: 命令模式屬於物件的行為模式。命令模式又稱為行動(Action)模式或交易(Transaction)模式。 命令模式把一個請求或者操作封裝到一個物件中。命令模式允許系統使用不同的請
Java設計模式6:介面卡模式
一、介面卡模式定義: 介面卡模式說的是,可以把一個類的介面變換成客戶端所期待的另一種介面,使得原本因介面不匹配而無法在一起工作的兩個類可以一起工作。 舉個例子:比方說我有一個檯燈,其插頭是標準的兩相的交流電插頭,即陽極、陰極。我旅遊到了一個地方想用自己的檯燈,但發現旅館裡