zoukankan      html  css  js  c++  java
  • 设计模式(二十三)访问者模式

    1、定义

      封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新操作。

    2、类型:行为类模式

    3、类图

       主要角色:

        抽象访问者:抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是visit方法中的参数定义哪些对象是可以被访问的;

        访问者:实现抽象访问者所声明的方法,它影响到访问者访问到一个类后该干什么,要做什么事情;

        抽象元素类:抽象类或者接口,声明接受哪一类访问者访问,程序上是通过accept方法中的参数来定义的,抽象类一般有两类方法,一部分是本身的业务逻辑,另外就是允许接收哪类访问者                                        来访问;

        元素类:实现抽象元素类所声明的accept方法,通常都是visitor.visit(this),基本上已经形成一种定式了;

        结构对象:一个元素的容器,一般包含一个容纳多个不同类、不同接口的容器,如List、Set、Map等,在项目中一般很少抽象出这个角色。

    4、代码实例

    1 /**
    2  * @author it-小林
    3  * @desc   元素接口
    4  * @date 2021年10月14日 19:38
    5  */
    6 public interface ComputerPart {
    7 
    8     public void accept(ComputerPartVisitor computerPartVisitor);
    9 }
     1 /**
     2  * @author it-小林
     3  * @desc   访问者接口
     4  * @date 2021年10月14日 19:39
     5  */
     6 public interface ComputerPartVisitor {
     7     public void visit(Computer computer);
     8     public void visit(Mouse mouse);
     9     public void visit(Keyboard keyboard);
    10     public void visit(Monitor monitor);
    11 }
     1 /**
     2  * @author it-小林
     3  * @desc   鼠标
     4  * @date 2021年10月14日 19:44
     5  */
     6 public class Mouse implements ComputerPart{
     7 
     8     @Override
     9     public void accept(ComputerPartVisitor computerPartVisitor) {
    10         computerPartVisitor.visit(this);
    11     }
    12 }
     1 /**
     2  * @author it-小林
     3  * @desc   键盘
     4  * @date 2021年10月14日 19:40
     5  */
     6 public class Keyboard implements ComputerPart{
     7     @Override
     8     public void accept(ComputerPartVisitor computerPartVisitor) {
     9         computerPartVisitor.visit(this);
    10     }
    11 }
     1 /**
     2  * @author it-小林
     3  * @desc   显示器
     4  * @date 2021年10月14日 19:42
     5  */
     6 public class Monitor implements ComputerPart{
     7     @Override
     8     public void accept(ComputerPartVisitor computerPartVisitor) {
     9         computerPartVisitor.visit(this);
    10     }
    11 }
     1 /**
     2  * @author it-小林
     3  * @desc   电脑
     4  * @date 2021年10月14日 19:45
     5  */
     6 public class Computer implements ComputerPart{
     7     ComputerPart[] parts;
     8 
     9     public Computer() {
    10         parts = new ComputerPart[]{new Mouse(), new Keyboard(), new Monitor()};
    11     }
    12 
    13     @Override
    14     public void accept(ComputerPartVisitor computerPartVisitor) {
    15         for (ComputerPart computerPart: parts) {
    16             computerPart.accept(computerPartVisitor);
    17         }
    18         computerPartVisitor.visit(this);
    19     }
    20 }
     1 /**
     2  * @author it-小林
     3  * @desc   具体访问者
     4  * @date 2021年10月14日 19:51
     5  */
     6 public class ComputerPartDisplayVisitor implements ComputerPartVisitor{
     7 
     8     @Override
     9     public void visit(Computer computer) {
    10         System.out.println("Displaying Computer.");
    11     }
    12 
    13     @Override
    14     public void visit(Mouse mouse) {
    15         System.out.println("Displaying Mouse.");
    16     }
    17 
    18     @Override
    19     public void visit(Keyboard keyboard) {
    20         System.out.println("Displaying Keyboard.");
    21     }
    22 
    23     @Override
    24     public void visit(Monitor monitor) {
    25         System.out.println("Displaying Monitor.");
    26     }
    27 }
     1 /**
     2  * @author it-小林
     3  * @desc   客户端
     4  * @date 2021年10月14日 19:54
     5  */
     6 public class Client {
     7     public static void main(String[] args) {
     8         ComputerPart computer = new Computer();
     9         computer.accept(new ComputerPartDisplayVisitor());
    10     }
    11 }

    5、优点

    • 符合单一职责原则;
    • 优秀的扩展性;
    • 灵活性。

    6、缺点

    • 具体元素对访问者公布细节,违反了迪米特原则;
    • 具体元素变更比较困难;
    • 违反了依赖倒置原则,依赖了具体类,没有依赖抽象。

    7、应用场景:

    1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作;
    2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。
    如本文有侵权行为,请及时与本人联系,多多包涵! 小生初出茅庐,多多指教!

    本文来自博客园,作者:it-小林,转载请注明原文链接:https://www.cnblogs.com/linruitao/p/15067890.html

  • 相关阅读:
    IE盒子模型和标准W3C盒子模型
    [转载] MVC3自定义标签,给Html.ActionLink加上支持图片链接的功能
    MVC3获取登录用户名
    [转]APS.netMVC的ViewModel问题
    [转载]Js小技巧||给input type=“password”的输入框赋默认值
    [资料]aspnetdb.mdf数据库的建立和使用
    [转] .net网页中插入Flash
    [转]Membership、MembershipUser和Roles类
    [小技巧]提交按钮
    asp.net mvc中session的使用 样例
  • 原文地址:https://www.cnblogs.com/linruitao/p/15067890.html
Copyright © 2011-2022 走看看