访问者模式
一般情况下是很少使用访问者模式,但如果需要使用访问者模式 那可能是真的需要了
了解访问者模式
什么是访问者模式?
比喻:游戏的补丁 在一个游戏中 一个牧师有三个技能 生命值 魔法值 治疗 在这里面生命值 魔法值 是角色自带的属性
治疗是角色的技能 。在1.0的版本中 牧师太弱了 为了加强牧师 我们在1.1版本对牧师的技能进行调整 增加了复活这一个技能
在这里面 技能这一块就相当于我们留着牧师角色类中的一个方法 这个方法通过调用访问者接口的实现类来实现不同的方法,并且
可以在后续继续增加牧师角色的技能或者是删除牧师角色的技能
访问者模式是做什么的?
数据结构与数据操作分离,解决稳定的数据结构加上易变的操作所产生的耦合问题
访问者模式的适用情景
1、 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些依赖于其具体类的操作。
2、 需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而你想避免让这些操作“污染”这些对象的类。Visitor模式使得你可以将相关的操作集中起来 定义在一个类中。
3、 当该对象结构被很多应用共享时,用Visitor模式让每个应用仅包含需要用到的操作。
4、定义对象结构的类很少改变,但经常需要在此结构上定义新的操作。改变对象结构类需要重定义对所有访问者的接口,这可能需要很大的代价。如果对象结构类经常改变,那么可能还是在这些类中定义这些操作较好。
简单来说就是:需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,使用访问者模式将这些封装到类中。
使用访问者模式的好处?
访问者模式把数据结构和作用于结构上的操作解耦合,使得操作集合可相对自由地演化。
符合单一职责原则:凡是适用访问者模式的场景中,元素类中需要封装在访问者中的操作必定是与元素类本身关系不大且是易变的操作,使用访问者模式一方面符合单一职责原则,另一方面,因为被封装的操作通常来说都是易变的,所以当发生变化时,就可以在不改变元素类本身的前提下,实现对变化部分的扩展。
扩展性良好:元素类可以通过接受不同的访问者来实现对不同操作的扩展。
代码:
1.先创建访问者的接口
public interface Visitor<T> {
//访问
void visitor(T t);
}
2.创建对象
package demo03.bean;
import demo03.visitor.Visitor;
public class User {
private String name;
private Integer age;
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
//用于扩展
public void visitor(Visitor visitor){
visitor.visitor(this);
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
3.实现访问者接口(实现的类可以通过自身的业务从而实现不同的功能)
import demo03.bean.User;
import demo03.visitor.Visitor;
//用于 添加User对象到数据库
public class SaveUserVisitorImpl implements Visitor<User> {
@Override
public void visitor(User user) {
System.out.println(user.getName()+"被存入数据库");
}
}
import demo03.bean.User;
import demo03.visitor.Visitor;
public class Delete implements Visitor<User> {
@Override
public void visitor(User user) {
System.out.println("删除数据库中的user:"+user.getName());
}
}
4.测试
import demo03.bean.User;
import demo03.visitor.Impl.Delete;
import demo03.visitor.Impl.SaveUserVisitorImpl;
public class Demo {
public static void main(String[] args) {
User zs = new User("zs", 18);
zs.visitor(new SaveUserVisitorImpl());
zs.visitor(new Delete());
}
}
测试结果
zs被存入数据库
删除数据库中的user:zs