设计模式之——访问者模式

一、基本介绍

访问者模式(行为型):将数据操作和数据结构分离的设计模式,即不直接去操作数据,通过中间一个数据结构去操作数据。

二、包含角色

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

2.具体访问者:实现抽象访问者角色中声明的各个访问操作,确定访问者访问每一个具体元素该进行什么样的操作。

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

4.具体元素角色:实现抽象元素角色提供的 accept() 操作,接收一个访问者对象,并回调访问者的具体访问方法。

5.对象结构角色:是一个包含具体元素角色的容器,提供让访问者对象遍历容器中的所有具体元素角色的方法,通常由 List、Set、Map 等聚合类实现。

三、案例及UML类图

案例说明:

           2020年是脱贫攻坚的最后一年,官员要具体去走访贫困家庭和低保户家庭,官员可能是村长,村委会主席、县长等,官员不确定,但走访的对象是确定的。

UML类图:

类Official:

public interface Official {

    void visitPoorFamilies(PoorFamilies poorFamilies);

    void visitLowInsuredFamilies(LowInsuredFamilies lowInsuredFamilies);
}

说明:官员接口,抽象访问者,定义每个官员走访的对象和接口。

类VillageHead:

public class VillageHead implements Official {

    @Override
    public void visitPoorFamilies(PoorFamilies poorFamilies) {
        System.out.println("村长带领"+poorFamilies.getName()+"脱贫!");
    }

    @Override
    public void visitLowInsuredFamilies(LowInsuredFamilies lowInsuredFamilies) {
        System.out.println("村长带领"+lowInsuredFamilies.getName()+"脱贫!");
    }
}

说明:村长类,具体访问者,实现各个访问操作,并且确定村长访问这些对象要进行什么样的操作。

类OvercomePovertyFamily:

public interface OvercomePovertyFamily {

    void accept(Official official);
}

说明:脱贫家庭接口,抽象元素角色,被访问需要脱贫的家庭接口定义,接收一个官员的访问。

类LowInsuredFamilies:

public class LowInsuredFamilies implements OvercomePovertyFamily {

    private String name = "低保户";

    @Override
    public void accept(Official official) {
        official.visitLowInsuredFamilies(this);
    }

    public String getName() {
        return name;
    }
}

说明:低保户家庭,具体元素角色,实现抽象元素角色的方法,并且当访问者(官员)到来时,调用访问者(官员)的访问低保户方法。

类PoorFamilies:

public class PoorFamilies implements OvercomePovertyFamily {

    private String name = "贫困家庭";

    @Override
    public void accept(Official official) {
        official.visitPoorFamilies(this);
    }

    public String getName() {
        return name;
    }
}

说明:贫困家庭,具体元素角色,实现抽象元素角色的方法,并且当访问者(官员)到来时,调用访问者(官员)的访问贫困户方法。

类ObjectStructure:

public class ObjectStructure {

    //需要访问的元素,即被访问元素
    private List<OvercomePovertyFamily> overcomePovertyFamilies = new ArrayList<>();

    /**
     * 添加一个被访问的元素
     * @param overcomePovertyFamily 需要脱贫的家庭
     */
    public void attach(OvercomePovertyFamily overcomePovertyFamily){
        overcomePovertyFamilies.add(overcomePovertyFamily);
    }

    /**
     * 官员开始走访
     * @param official 官员
     */
    public void visit(Official official) {
        for(OvercomePovertyFamily o : overcomePovertyFamilies) {
            o.accept(official);
        }
    }
}

说明:对象结构类,对象结构角色,添加被访问者和调用访问操作,隔离访问者和被访问者。

类VisitorTest:

public class VisitorTest {


    public static void main(String[] args) {
        //贫困家庭
        OvercomePovertyFamily o1 = new PoorFamilies();
        //低保户
        OvercomePovertyFamily o2 = new LowInsuredFamilies();
        //结构对象,存储被访问者
        ObjectStructure objectStructure = new ObjectStructure();
        objectStructure.attach(o1);
        objectStructure.attach(o2);
        //官员,村长
        Official villageHead = new VillageHead();
        //村长走访
        objectStructure.visit(villageHead);

    }
}

说明:测试及客户端类。

 

五、优缺点

优:

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

     2.对于访问者来说,是符合开闭原则的,是可以拓展的。

缺:

      1.类比较多,增加了代码的复杂度。

      2.对于被访问者来说,是不符合开闭原则的,每增加一个被访问者,则访问者就需要添加新的方法去进行操作。

 

六、适用场景

1.操作对象(被访问者)结构相对稳定,但其操作算法(访问者)经常变化的程序。

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

发布了35 篇原创文章 · 获赞 61 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/m0_37914588/article/details/103922390
今日推荐