• 公用技术——设计模式22——行为型模式——访问者模式


    1、概念

      在不修改原始类结构的基础上,将原始类的某种功能委托给访问者类来实现。

      它的核心思想是”duck-typing”,忽略原始类结构,抽象其公共的功能。

      理解访问者模式的关键点,我认为有以下几点:

    1. 为什么原始类不能自己实现这种功能,一方面这个功能与类结构确实无关,例如序列化,另外一个方面这个功能有公共的步骤,例如迭代器可以被抽象为next,hasNext,这种功能通常是某些类的公共功能,如果因为实现此功能,而对所有类进行修改基本不可能。
    2. 原始类与访问者类之间的关系,如果是依赖关系,可以是构造器参数,方法返回值,方法参数,属性等等这些形式,如果是泛化关系,原始类需要实现访问者类的接口。

      例如序列化,首先原始类实现Serializable接口,而后某种其他机制实现序列化功能。

      迭代器模式只是访问者模式的一种特例,功能只有遍历功能。

      策略模式中功能是由原始类提供,而将不同的实现方式委托给其他类。访问者模式中功能和实现方式都委托给其他类,还是存在一定的差异。

      我感觉模仿Java实现迭代,比较这些功能的方式比较好,提供两个接口

    1. 第一个接口类似于Comparable,用于标识原始类是否拥有此功能。
    2. 第二个接口类似于Comparator,用于提供此功能的实现方式,不同实现类提供不同的实现方式。

    2、UML图

    3、代码

      没有固定的类结构,此处省略。

    4、讨论

      以生活中的一个示例讨论一下,人---->交通工具。

      首先人有很多种角度,可以分为男女,可以分为父亲,母亲,儿子,女儿等等。假设系统存在很多类,它们本质都是人的抽象,但是类型却不同,例如存在User类,Employee类,Customer类,此时需要添加一种公共的功能,远行(抽象的代表从一个地方移动到另外一个地点)。

      设计Walkable(抽象的代表是否需要远行),例如Role类,它虽然是人的抽象,但是并不需要实现此接口。

      所有的这些类都实现Walkable接口,设计具体的Transfer接口,它用于抽象代表人的移动方式,可以是跑,走,可以使用交通工具,自行车,摩托车,电动车,汽车,公交车,出租车,火车,飞机,地铁等等。

      从上述理解访问者模式的两个关键问题,

      问题1:为什么原始类不能自己实现远行功能?

      答:第一原始类的基数较大,每个类都添加这个功能会很繁琐。第二这个功能与原始类的类型没有任何关系,只要它是人的抽象,便可以实现此功能。

      假设原始类是有限的,每一个都实现了此功能,例如提供了walk(Transfer transfer)方法,此时它就是策略模式,由Transfer接口提供具体的交通方式。

      问题2:原始类和委托类之间的关系?

      答:可以是依赖关系,例如构造器方法,属性,方法返回值,方法参数等等,但是更好的方式是委托类使用泛型,其中泛型T抽象的代表原始类。而用Walkable表示泛型的上限。

    5、示例

      集合的排序,类的比较,类的序列化。它没有固定的格式,只要理解duck-typing这种思想即可。

  • 相关阅读:
    zepto.js介绍
    box-sizing属性
    响应式网页高度自适应原理
    固定-比例-固定
    常用的js正则验证
    mysql之连接查询(多表查询)
    数据约束
    mysql表数据的增删改查
    mysql学习之数据库管理与表管理
    滑动选项卡的制作
  • 原文地址:https://www.cnblogs.com/rain144576/p/9940848.html
Copyright © 2020-2023  润新知