android设计模式二十三式(二十一)——访问者模式(Visitor)

    xiaoxiao2022-07-13  134

    访问者模式

    访问者模式,主要的作用就是把数据结构和针对数据结构上的操作进行解耦,适用于数据结构稳定,但是针对数据的操作容易变化的场景,访问者模式,改变操作数据的方法容易,但是改变数据结构困难,如果数据结构经常变化,则不能使用此模式

    先来确定一下访问者模式的组成

    被访问者接口:提供接收访问方法

    被访问者:接收访问,将自己的提供给访问者,自己的结构不易变化

    访问者接口:提供不同的访问方法

    访问者:访问数据,对针对数据的结构有不同的造作。

     

    我们还是来举个栗子:

    每个员工都有工龄和工资,公司按照工龄来计算工资,社保局根据工资和工龄来计算是否符合退休条件以及退休工资

    这里抽象一个员工接口,接收访问

    具体一个人实现接口,包含姓名,工龄,工资

    再抽象一个机构接口,可以访问员工的信息

    公司和社保局实现机构接口,处理自己的逻辑。

    /** * @author: hx * @Time: 2019/5/23 * @Description: Org */ public interface Org { void visit(Person person); } /** * @author: hx * @Time: 2019/5/23 * @Description: employee */ public interface employee { void accept(Org org); } /** * @author: hx * @Time: 2019/5/23 * @Description: Person */ public class Person implements employee { private String name; private int workingAge; private double salary; public Person(String name, int workingAge, double salary) { this.name = name; this.workingAge = workingAge; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getWorkingAge() { return workingAge; } public void setWorkingAge(int workingAge) { this.workingAge = workingAge; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public void accept(Org org) { org.visit(this); } } /** * @author: hx * @Time: 2019/5/23 * @Description: Company */ public class Company implements Org { @Override public void visit(Person person) { if (person.getWorkingAge() > 5){ System.out.println(person.getName()+"当前薪资"+person.getSalary()+",涨薪100"); }else if (person.getWorkingAge() > 10){ System.out.println(person.getName()+"当前薪资"+person.getSalary()+",涨薪500"); }else{ System.out.println(person.getName()+"当前薪资"+person.getSalary()+",不涨薪"); } } } /** * @author: hx * @Time: 2019/5/23 * @Description: SocialSecurityBureau */ public class SocialSecurityBureau implements Org { @Override public void visit(Person person) { if (person.getWorkingAge() < 15) { System.out.println(person.getName()+"不符合退休条件"); }else { System.out.println(person.getName()+"退休工资为:"+(person.getWorkingAge()*10 + person.getSalary()*0.8)); } } }

    来看一下怎么访问

    public static void main(String[] args){ Person person1 = new Person("小明",3,3000D); Person person2 = new Person("小红",6,5000D); Person person3 = new Person("小张",11,8000D); Person person4 = new Person("小王",16,10000D); person1.accept(new Company()); person1.accept(new SocialSecurityBureau()); person2.accept(new Company()); person2.accept(new SocialSecurityBureau()); person3.accept(new Company()); person3.accept(new SocialSecurityBureau()); person4.accept(new Company()); person4.accept(new SocialSecurityBureau()); } 输出结果: 小明当前薪资3000.0,不涨薪 小明不符合退休条件 小红当前薪资5000.0,涨薪100 小红不符合退休条件 小张当前薪资8000.0,涨薪100 小张不符合退休条件 小王当前薪资10000.0,涨薪100 小王退休工资为:8160.0

    功能已经实现,但是可以看到,调用的时候特别麻烦,也可以看到,在实际调用的时候,组织的实现类不能调用接口,所以,访问者模式是不符合依赖倒转原则的。所以才会有对数据结构的稳定性有要求。

    上面的调用其实也可以一个管理类中集中管理起来

    /** * @author: hx * @Time: 2019/5/23 * @Description: People */ public class People { private List<Person> mPeople = new ArrayList<>(); public void addPerson(Person person){ mPeople.add(person); } public void accept(Org org){ for (Person person : mPeople){ person.accept(org); } } }

    再看一下调用

    public static void main(String[] args){ Person person1 = new Person("小明",3,3000D); Person person2 = new Person("小红",6,5000D); Person person3 = new Person("小张",11,8000D); Person person4 = new Person("小王",16,10000D); People people = new People(); people.addPerson(person1); people.addPerson(person2); people.addPerson(person3); people.addPerson(person4); people.accept(new Company()); people.accept(new SocialSecurityBureau()); } 输出结果: 小明当前薪资3000.0,不涨薪 小红当前薪资5000.0,涨薪100 小张当前薪资8000.0,涨薪100 小王当前薪资10000.0,涨薪100 小明不符合退休条件 小红不符合退休条件 小张不符合退休条件 小王退休工资为:8160.0

    比第一种稍稍好一点

    优点

      增加新的访问操作十分方便

           每个访问者类的职责更加清晰

      将有关元素对象的访问行为集中到一个访问者对象中,而不是分散在一个个的元素类中,集中管理

    缺点

      增加新的元素类很困难,违背了开闭原则

           访问者访问的是实现类而不是接口,违背了依赖倒转原则

    应用场景

      一个对象结构包含多个类型的对象,对这些对象的造作依赖具体实现。 不同的类型可以有不同的访问操作

      数据结构对象结构不会改变,但经常需要在此对象结构上定义新的操作。

     

    最新回复(0)