设计模式之访问者模式
来源:互联网 发布:nodejs获取windows ip 编辑:程序博客网 时间:2024/05/06 12:53
为什么要使用访问者设计模式?
先看一下下面这段代码
class Person{private String action ;private String name;public Person(String name){this.name = name;}public String getAction() {return action;}public void setAction(String action) {this.action = action;}public void getConclusion(){if(action == "Happy"){System.out.println(name+" feel "+"Happy");}else if(action == "Exciting"){System.out.println(name+" feel "+"Exciting");}else if(action == "Grieved"){System.out.println(name+" feel "+"Grieved");}}}public class Client {public static void main(String [] args){Person person = new Person("jeason");person.setAction("Happy");person.getConclusion();}}
如果需要添加一种feeling那么需要去改动Person类,这里违背了开放封闭原则,getConclusion()需要对每种feeling都分别做操作,这里违背了单一职责原则.现在我们利用访问者模
式就可以就可以避免违反的两种原则.
什么是访问者设计模式?
表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。
涉及角色:
1.Visitor 抽象访问者角色,为该对象结构中具体元素角色声明一个访问操作接口。该操作接口的名字和参数标识了发送访问请求给具体访问者的具体元素角色,这样访问者就可以通过该元素角色的特定接口直接访问它。
2.ConcreteVisitor.具体访问者角色,实现Visitor声明的接口。
3.Element 定义一个接受访问操作(accept()),它以一个访问者(Visitor)作为参数。
4.ConcreteElement 具体元素,实现了抽象元素(Element)所定义的接受操作接口。
5.ObjectStructure 结构对象角色,这是使用访问者模式必备的角色。它具备以下特性:能枚举它的元素;可以提供一个高层接口以允许访问者访问它的元素;如有需要,可以设计成一个复合对象或者一个聚集(如一个列表或无序集合)。
访问者模式的几个特点:
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。
访问者模式适用于数据结构相对稳定算法又易变化的系统。因为访问者模式使得算法操作增加变得容易。若系统数据结构对象易于变化,经常有新的数据对象增加进来,则不适合使用访问者模式。
访问者模式的优点是增加操作很容易,因为增加操作意味着增加新的访问者。访问者模式将有关行为集中到一个访问者对象中,其改变不影响系统数据结构。其缺点就是增加新的数据结构很困难。
怎么使用访问者设计模式?
我们根据之前的需求和访问者模式的概念设计出UML:
具体代码:
State.class
public abstract class State {public abstract void eflectPerson(Person person);}
Happy.class
public class Happy extends State{@Overridepublic void eflectPerson(Person person) {// TODO Auto-generated method stubSystem.out.println(person.getName()+" feel happy");}}
Grieved.class
public class Grieved extends State{@Overridepublic void eflectPerson(Person person) {// TODO Auto-generated method stubSystem.out.println(person.getName()+" feel grieved");}}
Exciting.class
public class Exciting extends State{@Overridepublic void eflectPerson(Person person) {// TODO Auto-generated method stubSystem.out.println(person.getName()+" feel exciting");}}
Person.class
public class Person {private String name;public Person(String name){this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}//双分派public void receiveState(State state){state.eflectPerson(this);}}
这里解释一下什么叫双分派:假设有A,B两个对象,对象A中有一个方法需要用到对象B的引用,而在这个方法中去调用对象B的方法会用到对象A的引用。它使得执行结果不仅取决
于B类而且还取决于A类.
PersonStructure.class
public class PersonStructure {private ArrayList<Person> arrayList = new ArrayList<Person>();public void addPerson(Person person){arrayList.add(person);}public void remove(Person person){arrayList.remove(person);}public void displayPersonName(){for(Person p : arrayList){System.out.println("person name "+p.getName());}}public void receiveState(State state){for(Person p : arrayList){p.receiveState(state);}}}
Client.class
public class Client {public static void main(String [] args){Person p1 = new Person("jeason");Person p2 = new Person("neo");Person p3 = new Person("kuku");PersonStructure personStructure = new PersonStructure();personStructure.addPerson(p1);personStructure.addPerson(p2);personStructure.addPerson(p3);personStructure.displayPersonName();personStructure.receiveState(new Happy());}}
最后输出:
person name jeason
person name neo
person name kuku
jeason feel happy
neo feel happy
kuku feel happy
- 设计模式之访问者
- 设计模式之访问者
- 设计模式之访问者模式
- 设计模式之--访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 【设计模式】之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 设计模式之访问者模式
- 搜罗备忘: SharePoint 2013/2010 JavaScript client model 对列表和站点的基本操作
- c# 实现类的序列化与反序列化 可保存于session viewstate cookie各种缓存中
- ORACLE:实例化 EM 配置文件时出错解决方案
- 关于快速排序qsort
- Unique Paths II
- 设计模式之访问者模式
- hdu1905 Pseudoprime numbers
- 【rzxt】DirectX功能在Windows8中有什么样的变化
- ERP系统容灾目标
- 8大你不得不知的Android调试工具
- 加了Transation依然出现LAZY错误,和OpenSessionInViewFilter作用及配置
- VisionMobile:2013年Q3移动开发者经济报告(二):第一章、2013年Q3设备领域的状况:拐点
- Extjs4 获取items子控件时使用Ext.getCmp返回undefined
- C#往数据库写入NULL