设计模式篇16-访问者模式

1.关系类图

2.访问者模式介绍

定义:将作用某种数据结构中各元素的操作分离出来封装成独立的类.使其不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构的每个元素提供多种访问方式.它对数据的操作与数据结构进行分离,是行为类模式中最复杂的一种模式

优点:
	1)扩展性好,能够在不修改对象结构中元素的情况下,对象结构中的元素添加新的功能
	2)复用性好,可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用性
	3)灵活性,访问者模式将数据结构作用于结构上的操作解耦,使得操作集合可相对自有地演化而不影响系统的数据结构
	4)符合单一职责原则.访问者模式把相关的行为封装到一起,构成一个访问者,使得每一个访问者功能都比较单一
缺点:
	1)增加新的元素很困难,在访问者模式中,每增加一个新的元素类,都要在每一个具体访问这类中增加相应的具体操作,这违背了"开闭原则"
	2)破坏封装,访问者模式中具体元素对访问者公布细节,这破坏了类的封装性
	3违反了依赖倒置原则.访问者模式依赖了具体类,而没有依赖抽象类

应用场景:
	当系统中存在类型稳定一类的数据结构时,可以使用访问者模式方便地实现该类型所有数据结构的不同操作,而又不会产生任何副作用(脏数据),就是当集合中的不同类型金星多重操作时,使用访问者模式
	1)对象结构很稳定,其操作算法经常变化的程序
	2)对象结构的对象需要提供多种不同且不相关的操作,而且要避免让这些操作变化影响对象的数据结构
	3)对象结构包含很多类型的对象,希望这些对象试试依赖一些具体类型的操作

3.代码实现

//抽象元素类
public interface Element {
          
   
    void accept(Visitor visitor);
}


//具体元素A类
public class ConcreteElementA implements Element {
          
   
    public void accept(Visitor visitor) {
          
   
        visitor.visit(this);
    }
    public String operationA() {
          
   
        return "具体元素A的操作。";
    }
}


//具体元素B类
public class ConcreteElementB implements Element {
          
   
    public void accept(Visitor visitor) {
          
   
        visitor.visit(this);
    }
    public String operationB() {
          
   
        return "具体元素B的操作。";
    }
}


//抽象访问者
public 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类
public 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());
    }
}


//对象结构角色
public 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);
    }
}


//客户端
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);
}
经验分享 程序员 微信小程序 职场和发展