访问者模式(数据与行为解耦)

本文介绍了访问者模式在Java中的应用,包括UML类图展示、JDK中SimpleFileVisitor的使用,以及如何通过实现IVisitor和IVisitable接口进行文件操作,如删除文件。
摘要由CSDN通过智能技术生成

目录

前言

UML

plantuml

类图

实战代码

SimpleFileVisitor

 FileVisitor 接口

 删除指定文件夹

模板

IVisitor

IVisitable

Client


前言

一个类由成员变量和方法组成,成员变量即是类的数据结构,方法则是类的行为。

如果一个类的数据结构稳定,但是行为多变,想要增加类的行为,就必须为类添加新的方法,违背了开闭原则。

使用访问者模式,则可以在不修改原有类的前提下定义新的操作,为类增加新的行为。

它能将类的数据结构和行为解耦,将多变的行为提取到访问者中,不同的访问者实现不同的行为。当类的行为变化时,只需要替换对应的访问者就能够修改类的行为了。

故访问者特别适用于数据结构相对稳定,而操作易于变化的场景。

UML

plantuml

@startuml
'https://plantuml.com/class-diagram

interface Visitable {
    + accept(Visitor) : void
}

class ConcreteVisitable {
    + accept(Visitor) : void
}

interface Visitor {
    + visit(IVisitable) : void
}

class ConcreteVisitorA {
    + visit(IVisitable) : void
}

class ConcreteVisitorB{
    + visit(IVisitable) : void
}

class Client {}

Visitable <|.. ConcreteVisitable
Visitor <|.. ConcreteVisitorA
Visitor <|.. ConcreteVisitorB

Visitable <..> Visitor

Client ..> Visitable
Client ..> Visitor

@enduml

类图

实战代码

SimpleFileVisitor

JDK 中 nio 的 Files 的 walkFileTree 方法使用了访问者模式来遍历文件树,使用时可以重写 SimpleFileVisitor 中的方法,对文件树下每个文件做相应操作。比如删除文件,复制文件,查找文件等等。

 FileVisitor 接口

可以看到 FileVisitor 接口定义了访问文件夹的前置/后置操作,访问文件操作,以及访问文件异常操作,SimpleFileVisitor 则是提供了空实现。

在实际使用时,创建自定义文件访问者类,实现 FileVisitor 接口或者直接继承 SimpleFileVisitor 类,然后实现接口中定义的方法。使用 walkFileTree 遍历文件树时传入不同的访问者则能够对应不同的文件操作逻辑,完美地将数据结构和操作行为分离

 删除指定文件夹

public class Client {

    public static void main(String[] args) throws IOException {
        Path directory = Paths.get("/data/file/abc");
        Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attributes) throws IOException {
                Files.delete(file); // this will work because it's always a File
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
                Files.delete(dir); //this will work because Files in the directory are already deleted
                return FileVisitResult.CONTINUE;
            }
        });
    }

}

模板

IVisitor

public interface IVisitor {
    void visit(IVisitable visitable);
}

public class Visitor1 implements IVisitor {
    public void visit(IVisitable visitable) {
        System.out.println("Visitor1");
    }
}

public class Visitor2 implements IVisitor {
    public void visit(IVisitable visitable) {
        System.out.println("Visitor2");
    }
}

IVisitable

public interface IVisitable {
    void accept(IVisitor visitor);
}

class Part implements IVisitable {
    String name;
    Integer value;

    public void accept(IVisitor visitor) {
        visitor.visit(this);
    }
}

Client

public class Client {
    public static void main(String[] args) throws IOException {
        IVisitable part = new Part();     
    
        IVisitor visitor1 = new Visitor1();
        part.accept(visitor1);

        IVisitor visitor2 = new Visitor2();
        part.accept(visitor2);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值