1.定义
访问者模式Visitor是⼀种⾏为设计模式, 它能将算法与其所作⽤的对象隔离开来。
需求:构建了一个IDC机房,要对每一个服务器的状态进行处理,要知道服务器在运行过程中,并不止运维这一个角色,而是由多种角色来组合的,比如运维工程师比较关注硬件的状态,软件工程师比较关注软件的状态,DBA工程师比较关注数据库的状态,每个人在看服务器的时候切入的角色都是不一样的。
每个观察这个服务器的人就是访问者模式的访问者,每个人关注的点不一样,那么每个人所做的后续处理也是不一样的,这便是我们所说的访问中,针对一个事物,多个 不同的访问者来查看时,是从不同的角度来切入的。
2.模式结构
3.
抽象的事物:目标事物
public interface Element { //接受访问者,并执行访问者行为 public void accept(Visitor visitor); }
访问者的顶层抽象
public interface Visitor { //某个具体访问者对于服务器要做什么事? void visit(Server server); }
访问者里面的具体事物:服务器
public class Server implements Element{ private String ip; //IP 地址 private String status; //当前状态,up、down private Integer appPid; // OA系统进程PID private Float dbfileSize; //数据库文件尺寸(G) public Server(String ip, String status, Integer appPid , Float dbfileSize) { this.ip = ip; this.status = status; this.appPid = appPid; this.dbfileSize = dbfileSize; } public Float getDbfileSize() { return dbfileSize; } public void setDbfileSize(Float dbfileSize) { this.dbfileSize = dbfileSize; } public String getIp() { return ip; } public void setIp(String ip) { this.ip = ip; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public Integer getAppPid() { return appPid; } public void setAppPid(Integer appPid) { this.appPid = appPid; } //执行访问者具体行为 @Override public void accept(Visitor visitor) { visitor.visit(this); } }
具体访问者:硬件工程师关注硬件
public class HardwareEngineer implements Visitor{ @Override public void visit(Server server) { if(server.getStatus().equals("down")){ System.out.println("硬件工程师报告:[" + server.getIp() + "]服务器已宕机,正在人工重启"); }else if(server.getStatus().equals("up")){ System.out.println("硬件工程师报告:[" + server.getIp() + "]服务器状态正常"); }else if(server.getStatus().equals("unknown")){ System.out.println("硬件工程师报告:[" + server.getIp() + "]服务器状态未知,正在排查故障"); } } }
具体访问者:软件工程师关注软件
public class SoftwareEngineer implements Visitor{ @Override public void visit(Server server) { if(server.getAppPid()==0){ System.out.println("软件工程师报告:[" + server.getIp() + "]服务器OA系统进程消失,正在尝试重启应用"); }else{ System.out.println("软件工程师报告:[" + server.getIp() + "]服务器OA系统运行正常"); } } }
具体访问者:DBA关注数据库状态
public class DBA implements Visitor { @Override public void visit(Server server) { if (server.getDbfileSize() > 10) { System.out.println("DBA报告:[" + server.getIp() + "]数据文件超过10G,正在做IO优化"); } else { System.out.println("DBA报告:[" + server.getIp() + "]数据文件未超过10G,不需要额外优化"); } } }
IDC机房:存放具体的服务器
public class IDC { List<Server> serverList = new ArrayList<>(); public IDC() { Server server1 = new Server("192.168.31.101", "up", 818872,1.2f); Server server2 = new Server("192.168.31.102", "unknown", 222465,0.8f); Server server3 = new Server("192.168.31.103", "down", 0,10.8f); Server server4 = new Server("192.168.31.104", "up", 0,6.3f); serverList.add(server1); serverList.add(server2); serverList.add(server3); serverList.add(server4); } //check方法提供巡检 public void check(Visitor visitor){ for(Server server:serverList){ server.accept(visitor); } }
客户端:决定使用哪些观察者
public class Client { public static void main(String[] args) { //客户端根据需要派人巡查 IDC idc = new IDC(); Visitor he = new HardwareEngineer(); idc.check(he); Visitor se = new SoftwareEngineer(); idc.check(se); Visitor dba = new DBA(); idc.check(dba); } }
4.访问者模式优点
开闭原则。 你可以引⼊在不同类对象上执⾏的新⾏为, 且⽆需对这些类做出修改。
访问者模式符合单一职责原则、让程序具有优秀的扩展性、灵活性非常高
访问者模式可以对功能进行统一,可以做报表、UI、拦截器与过滤器,适用于数据结构相对稳定的系统
5.访问者模式缺点
每次在元素层次结构中添加或移除⼀个类时, 你都要更新所有的访问者。
6.使用场景
需要将数据与各种多种外在动作解耦时使⽤访问者模式
转载请注明:西门飞冰的博客 » 设计模式—访问者模式