由于blog各种垃圾评论太多,而且本人审核评论周期较长,所以懒得管理评论了,就把评论功能关闭,有问题可以直接qq骚扰我

设计模式—访问者模式

JAVA 西门飞冰 901℃
[隐藏]

1.定义

访问者模式Visitor是⼀种⾏为设计模式, 它能将算法与其所作⽤的对象隔离开来。

需求:构建了一个IDC机房,要对每一个服务器的状态进行处理,要知道服务器在运行过程中,并不止运维这一个角色,而是由多种角色来组合的,比如运维工程师比较关注硬件的状态,软件工程师比较关注软件的状态,DBA工程师比较关注数据库的状态,每个人在看服务器的时候切入的角色都是不一样的。

每个观察这个服务器的人就是访问者模式的访问者,每个人关注的点不一样,那么每个人所做的后续处理也是不一样的,这便是我们所说的访问中,针对一个事物,多个 不同的访问者来查看时,是从不同的角度来切入的。

2.模式结构

image-20221003131034436

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.使用场景

需要将数据与各种多种外在动作解耦时使⽤访问者模式

转载请注明:西门飞冰的博客 » 设计模式—访问者模式

喜欢 (0)or分享 (0)