zoukankan      html  css  js  c++  java
  • 访问者模式

    定义:有些集合对象中存在多种不同的元素,且每种元素也存在多种不同的访问者和处理方式,这些被处理的数据元素相对稳定而访问方式多种多样的数据结构,使用访问者来处理比较方便,访问者模式把处理方法从数据结构中分离出来,并根据需要添加新的处理方法,且不用修改原来的代码和数据结构,这提高了程序的扩展性和灵活性。

    优点:

    访问者模式是一种对象行为模式

    1, 扩展性好:能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能。

    2,复用性好,可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度。

    3,灵活性好,访问者模式将数据结构与作用与结构上的操作解耦,使得操作集合可相对自由的演化而不影响系统的数据结构

    4,符合单一职责原则,访问者模式把相关行为封装在一起,构成一个访问者,使每一个访问者的功能都比较单一。

    缺点:

    1,增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体类中增加相应的具体操作,这违背了开闭原则

    2,破坏封装性,访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性

    3,违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。

    模式的结构与实现

    访问者模式实现的关键是如何将作用于元素的操作分离出来封装成独立的类,

    模式结构

    1,抽象访问者角色:定义一个访问具体元素的接口,为每一个具体元素对应一个访问操作(visit),该操作中的参数类型标识了被访问的具体元素

    2,具体访问者角色:实现抽象访问者角色中声明的各个访问操作,确定访问者访问一个元素时该做什么

    3,抽象元素角色:声明一个包含接受操作accept()的接口,被接受的访问者对象作为accept()方法的参数.

    4,具体元素角色:实现抽象元素提供的accept()操作,其方法体通常都是visitor.visit(this),另外具体元素中肯能还包含本身业务逻辑的相关操作

    5,对象结构角色:是一个包含元素角色的容器,提供让访问者对象遍历容器中所有元素的方法,通常由list,set,map等聚合类实现

    结构图:

    应用场景

    1,对象结构相对稳定,但操作算法经常变化的程序。

    2,对象结构中的对象需要提供多种不同且不相关的操作,而且要避免让这些操作的变化影响对象的结构。

    3,对象结构  包含很多类型的对象,希望对这些对象实施一些依赖于其具体类型的操作。

    代码实现

    package visitor;
    import java.util.*;
    public class VisitorPattern
    {
        public static void main(String[] args)
        {
            ObjectStructure os=new ObjectStructure();
            os.add(new ConcreteElementA());
            os.add(new ConcreteElementB());
            Visitor visitor=new ConcreteVisitorA();
            os.accept(visitor);
            System.out.println("------------------------");
            visitor=new ConcreteVisitorB();
            os.accept(visitor);
        }
    }
    //抽象访问者
    interface Visitor
    {
        void visit(ConcreteElementA element);
        void visit(ConcreteElementB element);
    }
    //具体访问者A类
    class ConcreteVisitorA implements Visitor
    {
        public void visit(ConcreteElementA element)
        {
            System.out.println("具体访问者A访问-->"+element.operationA());
        }
        public void visit(ConcreteElementB element)
        {
            System.out.println("具体访问者A访问-->"+element.operationB());
        }
    }
    //具体访问者B类
    class ConcreteVisitorB implements Visitor
    {
        public void visit(ConcreteElementA element)
        {
            System.out.println("具体访问者B访问-->"+element.operationA());
        }
        public void visit(ConcreteElementB element)
        {
            System.out.println("具体访问者B访问-->"+element.operationB());
        }
    }
    //抽象元素类
    interface Element
    {
        void accept(Visitor visitor);
    }
    //具体元素A类
    class ConcreteElementA implements Element
    {
        public void accept(Visitor visitor)
        {
            visitor.visit(this);
        }
        public String operationA()
        {
            return "具体元素A的操作。";
        }
    }
    //具体元素B类
    class ConcreteElementB implements Element
    {
        public void accept(Visitor visitor)
        {
            visitor.visit(this);
        }
        public String operationB()
        {
            return "具体元素B的操作。";
        }
    }
    //对象结构角色
    class ObjectStructure
    {   
        private List<Element> list=new ArrayList<Element>();   
        public void accept(Visitor visitor)
        {
            Iterator<Element> i=list.iterator();
            while(i.hasNext())
            {
                ((Element) i.next()).accept(visitor);
            }      
        }
        public void add(Element element)
        {
            list.add(element);
        }
        public void remove(Element element)
        {
            list.remove(element);
        }
    }
  • 相关阅读:
    使用PLSql连接Oracle时报错ORA-12541: TNS: 无监听程序
    算法7-4:宽度优先搜索
    R语言字符串函数
    notepad++ 正则表达式
    MySQL常用命令
    linux下对符合条件的文件大小做汇总统计的简单命令
    Linux系统下统计目录及其子目录文件个数
    R: count number of distinct values in a vector
    ggplot2 demo
    R programming, In ks.test(x, y) : p-value will be approximate in the presence of ties
  • 原文地址:https://www.cnblogs.com/cwb123/p/13984808.html
Copyright © 2011-2022 走看看