访问者设计模式

一、定义

访问者模式的英文翻译是 Visitor Design Pattern。在 GoF 的《设计模式》一书中,它 是这么定义的:

Allows for one or more operation to be applied to a set of objects at runtime, decoupling the operations from the object structure

允许一个或者多个操作应用到一组对象上,解耦操作和对象本身。就是将操作方式的扩展与操作的目标对象的扩展分离开,互不影响,所以,比如需要使用组合的方式。

二、类图关系

在这里插入图片描述

这个关系图与《桥接模式》很类似,但是使用场景不同:桥接模式是将抽象与实现进行解耦,而访问者是将操作行为与操作对象进行解耦。

三、案例

场景描述:对传入的编码文件进行压缩和加密处理。

创建访问者接口,注意,接口实际操作的对象是具体实现类,也就是说,访问者模式为了实现拓展的灵活和单一职责而违背了迪米特法则和依赖倒置原则

/**
 * 访问者接口:内部集成对编码的操作
 */
public interface Visitor {

    /**
     * 提供两个重载方法:分别处理UTF-8文件和GBK文件
     */
    void executeUTF8File(UTF8EncodeFile utf8EncodeFile);
    void executeGBKFile(GBKEncodeFile gbkEncodeFile);
}

/**
 * 压缩文件处理
 */
@Slf4j
public class Compressor implements Visitor {
    @Override
    public void executeUTF8File(UTF8EncodeFile utf8EncodeFile) {
        log.info("压缩UTF-8文件!");
    }

    @Override
    public void executeGBKFile(GBKEncodeFile gbkEncodeFile) {
        log.info("压缩GBK文件!");
    }
}

/**
 * 加密文件
 */
@Slf4j
public class Encryptor implements Visitor {
    @Override
    public void executeUTF8File(UTF8EncodeFile utf8EncodeFile) {
        log.info("加密UTF-8文件……");
    }

    @Override
    public void executeGBKFile(GBKEncodeFile gbkEncodeFile) {
        log.info("加密GBK文件……");
    }
}

创建目标对象抽象类——编码文件

/**
 * 需要编码的文件
 */
public abstract class EncodingFile {

    /**
     * 抽象方法,对编码进行操作,将访问者传入
     */
    public abstract void accept(Visitor visitor);
}

/**
 * GBK编码文件
 */
public class GBKEncodeFile extends EncodingFile {
    @Override
    public void accept(Visitor visitor) {
        visitor.executeGBKFile(this);
    }
}

/**
 * UTF-8格式文件
 */
public class UTF8EncodeFile extends EncodingFile {

    /**
     * 执行文件
     */
    @Override
    public void accept(Visitor visitor) {
        visitor.executeUTF8File(this);
    }
}

测试

/**
 * 访问者模式测试
 */
@RunWith(JUnit4.class)
public class VisitorTest {

    /**
     * 测试压缩和加密文件
     */
    @Test
    public void testCompressAndEncry() {

        //创建压缩文件访问者
        Compressor compressor = new Compressor();

        //获取文件并循环压缩处理
        createFile().forEach(e -> e.accept(compressor));

        //创建加密文件者
        Encryptor encryptor = new Encryptor();

        //获取文件并循环加密
        createFile().forEach(e -> e.accept(encryptor));
    }

    /**
     * 创建文件
     */
    private List<EncodingFile> createFile() {
        return Lists.newArrayList(
                new GBKEncodeFile(),
                new UTF8EncodeFile()
        );
    }
}

[main] INFO  c.j.s.v.i.Compressor - 压缩GBK文件!
[main] INFO  c.j.s.v.i.Compressor - 压缩UTF-8文件!
[main] INFO  c.j.s.v.i.Encryptor - 加密GBK文件……
[main] INFO  c.j.s.v.i.Encryptor - 加密UTF-8文件……
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值