博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
访问者模式
阅读量:6898 次
发布时间:2019-06-27

本文共 5473 字,大约阅读时间需要 18 分钟。

《大话设计模式》阅读笔记和总结。原书是C#编写的,本人用Java实现了一遍,包括每种设计模式的UML图实现和示例代码实现。

目录:
Github地址:

说明

定义:访问者模式(Visitor),表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

UML图:

img_3b2c8ac8d738a1c682ba09d2b617683d.png
访问者模式UML图.png

代码实现:

Visitor类,为该对象结构中ConcreteElement的每一个类声明一个Visit操作

abstract class Visitor{    public abstract void VisitConcreteElementA(ConcreteElementA elementA);    public abstract void VisitConcreteElementB(ConcreteElementB elementB);}

ConcreteVisitor1和ConcreteVisitor2类,具体访问者,实现每个由Visitor声明的操作。每个操作实现算法的一部分,而该算法片段是对应于结构中对象的类

class ConcreteVisitor1 extends Visitor {    @Override    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {        System.out.println(concreteElementA.getClass().getSimpleName() + "被"                + this.getClass().getSimpleName() + "访问");    }    @Override    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {        System.out.println(concreteElementB.getClass().getSimpleName() + "被"                + this.getClass().getSimpleName() + "访问");    }}class ConcreteVisitor2 extends Visitor {    @Override    public void VisitConcreteElementA(ConcreteElementA concreteElementA) {        System.out.println(concreteElementA.getClass().getSimpleName() + "被"                + this.getClass().getSimpleName() + "访问");    }    @Override    public void VisitConcreteElementB(ConcreteElementB concreteElementB) {        System.out.println(concreteElementB.getClass().getSimpleName() + "被"                + this.getClass().getSimpleName() + "访问");    }}

Element类,定义一个Accept操作,它以一个访问者为参数

abstract class Element{    public abstract void Accept(Visitor visitor);}

ConcreteElementA和ConcreteElementB类,具体元素,实现Accept操作

class ConcreteElementA extends Element{    @Override    public void Accept(Visitor visitor) {        visitor.VisitConcreteElementA(this);    }    public void OperationA(){    }}class ConcreteElementB extends Element{    @Override    public void Accept(Visitor visitor) {        visitor.VisitConcreteElementB(this);    }    public void OperationB(){    }}

ObjectStructure类,能枚举它的元素,可以提供一个高层的接口以允许访问者访问它的元素

class ObjectStructure{    private List
elements = new ArrayList<>(); public void Attach(Element element){ elements.add(element); } public void Detach(Element element){ elements.remove(element); } public void Accept(Visitor visitor){ for (Element e :elements) { e.Accept(visitor); } }}

客户端代码

public class VisitorPattern {    public static void main(String[] args){        ObjectStructure o = new ObjectStructure();        o.Attach(new ConcreteElementA());        o.Attach(new ConcreteElementB());        ConcreteVisitor1 v1 = new ConcreteVisitor1();        ConcreteVisitor2 v2 = new ConcreteVisitor2();        o.Accept(v1);        o.Accept(v2);    }}

运行结果

ConcreteElementA被ConcreteVisitor1访问ConcreteElementB被ConcreteVisitor1访问ConcreteElementA被ConcreteVisitor2访问ConcreteElementB被ConcreteVisitor2访问

示例

例子:程序要求实现当男人和女人在不同状态下的反应。

男人成功时,背后多半有一个伟大的女人。

女人成功时,背后多半有一个伟大的男人。
男人失败时,闷头喝酒,谁也不用劝。
女人失败时,眼泪汪汪,谁也劝不了。
男人恋爱时,凡是不懂也要装懂。
女人恋爱时,遇事懂也装作不懂。
男女对比这么多的原因就是因为人类在性别上就只有男人和女人两类。

UML图:

img_c5acd55cc7017a5c1725f1c1210c8753.png
访问者模式示例UML图.png

代码实现:

抽象元素

public abstract class Person {    public abstract void Accept(Action action);}

男人

public class Man extends Person{    @Override    public void Accept(Action action) {        action.GetManConclusion(this);    }}

女人

public class Woman extends Person{    @Override    public void Accept(Action action) {        action.GetWomanConclusion(this);    }}

抽象状态类

public abstract class Action {    public abstract void GetManConclusion(Person man);    public abstract void GetWomanConclusion(Person woman);}

成功状态

public class Success extends Action{    @Override    public void GetManConclusion(Person man) {        System.out.println("男人成功时");    }    @Override    public void GetWomanConclusion(Person woman) {        System.out.println("女人成功时");    }}

失败状态

public class Failing extends Action{    @Override    public void GetManConclusion(Person man) {        System.out.println("男人失败时");    }    @Override    public void GetWomanConclusion(Person woman) {        System.out.println("女人失败时");    }}

恋爱状态

public class Amativeness extends Action {    @Override    public void GetManConclusion(Person man) {        System.out.println("男人恋爱时");    }    @Override    public void GetWomanConclusion(Person woman) {        System.out.println("女人恋爱时");    }}

结婚状态

public class Marriage extends Action{    @Override    public void GetManConclusion(Person man) {        System.out.println("男人结婚时...");    }    @Override    public void GetWomanConclusion(Person woman) {        System.out.println("女人结婚时...");    }}

对象结构,用于访问男,女元素

public class PersonObjectStructure {    //对象结构,用于访问男,女元素    private List
list = new ArrayList<>(); public void Attach(Person person) { list.add(person); } public void Detach(Person person) { list.remove(person); } public void Display(Action action) { for (Person person : list) { person.Accept(action); } }}

客户端代码

public class Main {    public static void main(String[] args) {        PersonObjectStructure objectStructure=new PersonObjectStructure();        objectStructure.Attach(new Man());        objectStructure.Attach(new Woman());        //看男人和女人在成功时的状态        Success success=new Success();        objectStructure.Display(success);        //新增一个结婚状态        Marriage marriage=new Marriage();        objectStructure.Display(marriage);    }}

运行结果

男人成功时女人成功时男人结婚时...女人结婚时...

转载地址:http://wscdl.baihongyu.com/

你可能感兴趣的文章
人工智能创业项目,创业服务资源渠道
查看>>
iOS使用SQLCipher加密数据库
查看>>
喜讯不断,BCH又迎来两个代币发行方案
查看>>
java B2B2C 源码多租户电子商城系统-Spring Cloud整合Netflix Archaius介绍
查看>>
Camera相机
查看>>
阿里云DMS发布数据库网关服务: 打通网络限制 开启数据库统一管理的万能钥匙...
查看>>
java保证唯一的递增的序列号字符串
查看>>
Nginx实现404页面的几种方法
查看>>
input输入框的change事件_无需整理
查看>>
隔时显示下一页
查看>>
分区找不到的文件怎么寻回
查看>>
Jenkins实战演练之Linux服务器快速搭建
查看>>
iOS异常处理学习笔记
查看>>
C语言宏的各种用法
查看>>
编译支持iOS7 和 Xcode5 FFmpeg 库
查看>>
Python中的列表、元祖、字典的区别
查看>>
Linux 文件权限操作
查看>>
自动化运维之saltstack(2)
查看>>
朴素贝叶斯法---朴素贝叶斯法的学习与分类
查看>>
统计学习方法概论---回归问题
查看>>