一步一步地理解Visitor模式
现在能找到的Visitor模式的讲解大都非常跳跃,问题列出来出后,讲着讲着就突然给出了生涩的UML类图和accept()、visit()等奇怪的方法名,让人非常费解; 读者即使理解了,也有囫囵吞枣的感觉,不能领会其精妙之处。
本文试图以问题为驱动,以代码重构的方式,展示我们是怎么样一步一步地解决问题,并选择visitor模式作为重构的终点。
#1.问题域
visitor模式用于遍历一群对象,这些对象按某种结构组织在一起(List, Set, Tree等)。这种场景常常面临的问题是:
组织里的对象的类型彼此不同,遍历者要根据不同的类型使用不同的逻辑,导致代码里频繁使用if语句,可读性、可维护性都会比较差
代码详见https://github.com/chenjianjx/learn-visitor-pattern/blob/master/1st-PlainSolution/src/learn/visitor/research/client/EmployeeClient.java
要消除if,最常见的方式就是把各个if里面的逻辑塞入到对象的各个子类中
#2.通过多态解决对象类型不同的问题private static void drink(Team team) throws Exception { DrinkVisitor visitor = new DrinkVisitor(); for (Employee employee : team.getEmployees()) { employee.accept(visitor); } } private static void printTitle(Team team) throws Exception { PrintTitleVisitor visitor = new PrintTitleVisitor(); for (Employee employee : team.getEmployees()) { employee.accept(visitor); } }
代码详见https://github.com/chenjianjx/learn-visitor-pattern/blob/master/5th-VisitorStyle/src/learn/visitor/research/client/EmployeeClient.java