访问者设计模式

访问者设计模式

模式定义

表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下,定义作用于这些元素的新操作

使用场景

  1. 对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作
  2. 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。

例子

定义被访问者学生。抽象了一个学生基类,随机数来模拟总成绩

public abstract class Students {
    public String name;
    public int totalScore; // 总成绩
    Students(String aName) {
        name = aName;
        totalScore = new Random().nextInt(100);
    }
    public abstract void accept(Visitor visitor);
}

然后我们定义了两种学生

// 体育生,随机数模拟成绩
public class SportsStudents extends Students {
    public int sports;

    public SportsStudents(String aName) {
        super(aName);
        sports = new Random().nextInt(100);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

// 美术生,随机数模拟成绩
public class ArtStudents extends Students {
    public int art;

    public ArtStudents(String aName) {
        super(aName);
        art = new Random().nextInt(100);
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
    }
}

先抽象出访问者的访问方法visit

public interface Visitor {
    public void visit(ArtStudents artStudents);
    public void visit(SportsStudents sportsStudents);
}

这里定义两个访问者,一个班主任,他关注总成绩和特长科目成绩。另一个特长老师,他只关心特长科目成绩

// 班主任
public class HeadmasterTeacherVisitor implements Visitor {
    private static String TAG = ArtStudents.class.getSimpleName();
    @Override
    public void visit(ArtStudents artStudents) {
        Log.d(TAG,"name = " + artStudents.name);
        Log.d(TAG,"totalScore = " + artStudents.totalScore);
        Log.d(TAG,"art = " + artStudents.art);
    }

    @Override
    public void visit(SportsStudents sportsStudents) {
        Log.d(TAG,"name = " + sportsStudents.name);
        Log.d(TAG,"totalScore = " + sportsStudents.totalScore);
        Log.d(TAG,"sports = " + sportsStudents.sports);
    }
}

// 特长老师
public class SpecialTeacherVisitor implements Visitor {
    private static String TAG = SpecialTeacherVisitor.class.getSimpleName();
    @Override
    public void visit(ArtStudents artStudents) {
        Log.d(TAG,"name = " + artStudents.name);
        Log.d(TAG,"art = " + artStudents.art);
    }

    @Override
    public void visit(SportsStudents sportsStudents) {
        Log.d(TAG,"name = " + sportsStudents.name);
        Log.d(TAG,"sports = " + sportsStudents.sports);
    }
}

根据不同的访问者和被访问者达到不同的操作目的,这里模拟把所有学生放到一个list里面。遍历的时候,被访问者students调用accept访问来同意访问

public class StudentsList {
    List<Students> list = new LinkedList<Students>();
    public StudentsList() {
        list.add(new ArtStudents("jack"));
        list.add(new ArtStudents("john"));
        list.add(new SportsStudents("lily"));
        list.add(new SportsStudents("sky"));
    }

    public void showStudentschievement(Visitor visitor) {
        for (Students students : list) {
            students.accept(visitor);
        }
    }
}

调用:

StudentsList list = new StudentsList();
list.showStudentschievement(new HeadmasterTeacherVisitor());
list.showStudentschievement(new SpecialTeacherVisitor());

输出:

 D/ArtStudents: name = jack
 D/ArtStudents: totalScore = 13
 D/ArtStudents: art = 52
 D/ArtStudents: name = john
 D/ArtStudents: totalScore = 98
 D/ArtStudents: art = 12
 D/ArtStudents: name = lily
 D/ArtStudents: totalScore = 51
 D/ArtStudents: sports = 23
 D/ArtStudents: name = sky
 D/ArtStudents: totalScore = 24
 D/ArtStudents: sports = 30
 D/SpecialTeacherVisitor: name = jack
 D/SpecialTeacherVisitor: art = 52
 D/SpecialTeacherVisitor: name = john
 D/SpecialTeacherVisitor: art = 12
 D/SpecialTeacherVisitor: name = lily
 D/SpecialTeacherVisitor: sports = 23
 D/SpecialTeacherVisitor: name = sky
 D/SpecialTeacherVisitor: sports = 30

总结

优点:

  1. 符合单一职责原则
  2. 优秀的扩展性以及灵活性

缺点:

  1. 具体元素对访问者公布细节,违反了迪米特原则
  2. 具体元素变更比较困难
  3. 违反了依赖倒置原则,依赖了具体类,没有依赖抽象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值