5

行为型设计模式之访问者模式_积跬步,至千里。的技术博客_51CTO博客

 1 year ago
source link: https://blog.51cto.com/chencoding/5819830
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

访问者模式

访问者模式属于行为型模式。它是一种将数据结构与数据操作分离的设计模式。是指封装一些作用于某种数据结构中的各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。

访问者模式被称为最复杂的设计模式,使用频率不高。

访问者模式最大的优点就是增加访问者非常容易,如果要增加一个访问者,只要新实现一个访问者接口的类,从而达到数据对象与数据操作相分离的效果。

1.数据结构稳定,作用于数据结构的操作经常变化的场景

2.需要数据结构与数据操作分离的场景

3.需要对不同数据类型(元素)进行操作,而不使用分支判断具体类型的场景

举例:饭馆吃饭,饭馆菜品相对固定,但每天去吃饭的人是变化的,人即访问者。

1.抽象访问者(Visitor)

接口或抽象类,定义了对每一个具体元素(Element)的访问行为visit()方法,其参数就是具体的元素(Element)对象

通常来说:Visitor的方法个数与元素(Element)个数是相等的。如果元素(Element)个数经常变动,会导致Visitor的方法也要进行变动

2.具体访问者(ConcreteVisitor)

实现对具体元素的操作

3.抽象元素(Element)

接口或抽象类,定义了一个接受访问者访问的方法accept(),表示所有元素类型都支持被访问者访问

4.具体元素(Concrete Element)

具体元素类型,提供接受访问者的具体实现。通常的实现都为:visitor.visit(this)

5.结构对象(ObjectStruture)

该类内部维护了元素集合,并提供方法接受访问者对该集合所有元素进行操作

行为型设计模式之访问者模式_java
1.解耦了数据结构与数据操作,使得操作集合可以独立变化

2.扩展性好:可以通过扩展访问者角色,实现对数据集的不同操作

3.元素具体类型并非单一,访问者均可操作

4.心各角色职责分离,符合单一职责原侧出前
1.无法增加元素类型:若系统数据结构对象易于变化,经常有新的数据对象增加进来,则访问者类必须增加对应元素类型的操作,违背开闭原则

2.具体元素变更困难:具体元素增加属性,删除属性等操作会导致对应的访问者类需要进行相应的修改,尤其当有大量访问者类时,修改范围太大

3.违背依赖倒置原则:访问者依赖的是具体元素类型,而不是抽象。

创建抽象访问者

public interface IVisitor {

    void visit(ConcreteElementA element);

    void visit(ConcreteElementB element);
}

创建具体访问者

public class ConcreteVisitorA implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.get();
        System.out.println("具体访问者ConcreteVisitorA,访问结果: " + result);
    }

    public void visit(ConcreteElementB element) {
        String result = element.get();
        System.out.println("具体访问者ConcreteVisitorA,访问结果: " + result);
    }
}
public class ConcreteVisitorB implements IVisitor {

    public void visit(ConcreteElementA element) {
        String result = element.get();
        System.out.println("具体访问者ConcreteVisitorB,访问结果: " + result);
    }


    public void visit(ConcreteElementB element) {
        String result = element.get();
        System.out.println("具体访问者ConcreteVisitorB,访问结果: " + result);
    }
}

创建抽象元素

public interface IElement {
    void accept(IVisitor visitor);
}

创建具体元素

public class ConcreteElementA implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public String get() {
        return "我是具体元素ConcreteElementA";
    }
}
public class ConcreteElementB implements IElement {

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }

    public String get() {
      return "我是具体元素ConcreteElementB";
    }
}

创建结构对象

public class ObjectStructure {
    private List<IElement> list = new ArrayList<IElement>();

    {
        this.list.add(new ConcreteElementA());
        this.list.add(new ConcreteElementB());
    }

    public void accept(IVisitor visitor) {
        for (IElement element : this.list) {
            element.accept(visitor);
        }
    }
}

客户端执行

    public static void main(String[] args) {
        // 结构对象
        ObjectStructure collection = new ObjectStructure();
        // 访问者A
        IVisitor visitorA = new ConcreteVisitorA();
        collection.accept(visitorA);
        System.out.println("------------------------------------");
        // 访问者B
        IVisitor visitorB = new ConcreteVisitorB();
        collection.accept(visitorB);
    }
具体访问者ConcreteVisitorA,访问结果: 我是具体元素ConcreteElementA
具体访问者ConcreteVisitorA,访问结果: 我是具体元素ConcreteElementB
------------------------------------
具体访问者ConcreteVisitorB,访问结果: 我是具体元素ConcreteElementA
具体访问者ConcreteVisitorB,访问结果: 我是具体元素ConcreteElementB

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK