Java描述设计模式(23):访问者模式

一、生活场景

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) 访问者依赖具体元素,不是抽象元素,面向细节编程,违背依赖倒转原则;

END

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!
### 回答1: Java设计模式是一套经过总结和整理的编程思想,用于解决软件开发中常见的问题。《Java设计模式23设计模式全面解析(超级详细)》是一本详细介绍这23设计模式的书籍,它可以帮助读者深入理解每种设计模式的原理和用法。 这本书分为23个章节,每个章节介绍一种设计模式。每个章节都从问题的背景出发,描述设计模式的目标和应用场景。然后,通过实例代码和图形示意来展示如何使用该设计模式解决问题。 书中详细介绍了创建型设计模式、结构型设计模式和行为型设计模式。在创建型设计模式方面,包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式等。结构型设计模式包括适配器模式、装饰器模式、代理模式、组合模式和桥接模式等。行为型设计模式包括策略模式、观察者模式、迭代器模式、命令模式和模板方法模式等。 每个设计模式都有其特定的使用场景和适用性,读者可以根据自己的需求选择合适的设计模式来解决问题。通过学习这本书,读者可以深入理解设计模式的原理和思想,并且能够应用到实际的软件开发中。 总的来说,《Java设计模式23设计模式全面解析(超级详细)》是一本对于Java开发者来说非常有价值的书籍。它通过详细的示例和解释,帮助读者深入理解23设计模式的使用方法,使读者能够灵活地应用设计模式解决实际开发中遇到的问题。无论是初学者还是有一定经验的开发者,都可以从这本书中受益匪浅。 ### 回答2: 《Java设计模式23设计模式全面解析(超级详细)》是一本介绍Java设计模式的全面解析书籍。设计模式是软件工程领域中的一种解决问题的思维方式和经验总结,能够提供可复用的解决方案。这本书详细介绍了23种经典的设计模式,包括创建型、结构型和行为型三种类型的模式。 在创建型设计模式方面,书中包含了单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式。这些模式都是用来创建对象的,通过不同的实现方式能够灵活地创建对象,并且符合原则,如单一职责原则、开闭原则等。 在结构型设计模式方面,书中介绍了适配器模式、装饰器模式、代理模式、外观模式等。这些模式通过组合不同的类和对象,来解决不同类间关系的问题,增加了程序的可扩展性和灵活性。 在行为型设计模式方面,书中讲解了观察者模式、模板方法模式、策略模式、命令模式等。这些模式着重于对象之间的通信和协作,通过定义不同的行为和规则,让对象能够更好地进行交互,降低了对象间的耦合度。 此外,书中还介绍了其他几种分类的设计模式,如迭代器模式、访问者模式、备忘录模式等,这些模式在特定的应用场景中发挥着重要作用。 总的来说,《Java设计模式23设计模式全面解析(超级详细)》是一本详细介绍了Java设计模式的书籍,对于想深入了解和应用设计模式Java开发人员来说,是一本很好的资料,能够帮助他们理解,并在实际项目中应用这些经典的设计模式。 ### 回答3: Java设计模式是一套被广泛应用于软件设计的规范和经验总结。设计模式可以提供可重用和可维护的代码,能够帮助开发人员解决常见的软件设计问题。 Java设计模式一共有23种,分为创建型模式、结构型模式和行为型模式三个类别。 创建型模式包括单例模式、工厂模式、抽象工厂模式、建造者模式和原型模式。单例模式确保一个类只有一个实例,工厂模式将对象的创建委托给工厂类,抽象工厂模式允许客户端使用抽象接口来创建一组相关对象,建造者模式通过一步步构建复杂对象,原型模式通过克隆已有对象来创建新对象。 结构型模式包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。适配器模式将一个类的接口转换成客户端期望的接口,桥接模式将抽象和实现分离,组合模式将对象组合成树形结构以表示“部分-整体”的层次结构,装饰器模式动态地给对象添加职责,外观模式为多个子系统提供一个统一的接口,享元模式共享对象以减少内存的使用,代理模式为其他对象提供一个代理以控制对这个对象的访问。 行为型模式包括模板方法模式、命令模式、迭代器模式、观察者模式、中介者模式、备忘录模式、解释器模式、状态模式、策略模式、职责链模式和访问者模式。模板方法模式定义了一个操作中的算法骨架,而将一些步骤延迟到子类中实现,命令模式将请求封装成对象,迭代器模式提供一种方法来顺序访问聚合对象的元素,观察者模式定义对象之间的一对多依赖关系,中介者模式定义了一个封装一组对象交互的对象,备忘录模式在不破坏封装的前提下捕获一个对象的内部状态,解释器模式为语言创建解释器,状态模式允许一个对象在其内部状态改变时改变其行为,策略模式定义了一系列算法,职责链模式将请求的发送者和接收者解耦,访问者模式将算法与数据结构分离开来。 这些设计模式在实际的软件开发中有着广泛的应用,对于提高代码的可重用性、可维护性和可扩展性都具有很好的作用。了解和熟练运用这些设计模式,对于Java开发人员来说是非常重要的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值