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 {@Overridepublic void accept(CrowdView view) {view.getYouthView(this);} } class MiddleAge extends Crowd {@Overridepublic void accept(CrowdView view) {view.getMiddleAgeView (this);} } /*** 不同人群觀念的管理*/ abstract class CrowdView {// 青年人觀念abstract void getYouthView (Youth youth);// 中年人觀念abstract void getMiddleAgeView (MiddleAge middleAge); } class Approve extends CrowdView {@Overridepublic void getYouthView(Youth youth) {System.out.println("青年人贊同電競");}@Overridepublic void getMiddleAgeView(MiddleAge middleAge) {System.out.println("中年人贊同電競");} } class Against extends CrowdView {@Overridepublic void getYouthView(Youth youth) {System.out.println("青年人反對電競");}@Overridepublic 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 {@Overridepublic void visit(NodeA node) {node.operationA() ;}@Overridepublic void visit(NodeB node) {node.operationB() ;} } class VisitorB implements Visitor {@Overridepublic void visit(NodeA node) {node.operationA() ;}@Overridepublic void visit(NodeB node) {node.operationB() ;} } /*** 抽象節點角色*/ abstract class Node {/*** 接收訪問者*/abstract void accept(Visitor visitor); } /*** 具體節點角色*/ class NodeA extends Node{@Overridepublic void accept(Visitor visitor) {visitor.visit(this);}public void operationA(){System.out.println("NodeA.operationA");} } class NodeB extends Node{@Overridepublic 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):访问者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LINUX技术讨论区
- 下一篇: DTMF--VAD 项目分析