【再探】设计模式—适配器、装饰及外观模式

发布于:2024-05-12 ⋅ 阅读:(30) ⋅ 点赞:(0)

 结构型设计模式是用于设计对象和类之间关系的一组设计模式。一共有7种:适配器模式、装饰器模式、外观模式、桥接模式、组合模式、享元模式及代理模式。

1 适配器模式

需求:在软件维护阶段,已存在的方法与目标接口不匹配,需要个中间类来适配这个方法。

1.1 适配器模式介绍

将一个类的接口转换成客户端期望的目标类格式,使得原本不兼容的类可以一起工作。

图 适配器模式 UML

public class AdapterPattern {

    public static void main(String[] args) {
        SimpleEncrypt simpleEncrypt = new SimpleEncrypt();
        EncryptAdapter adapter = new EncryptAdapter(simpleEncrypt);
        String encrypt = adapter.encrypt("hello adapter");
        System.out.println(encrypt);
    }

    private interface Encrypt {
        String encrypt(String text);
    }

    private static class EncryptAdapter implements Encrypt{

        private static final int ENCRYPT_LENGTH = 15;

        private final SimpleEncrypt simpleEncrypt;

        private EncryptAdapter(SimpleEncrypt simpleEncrypt) {
            this.simpleEncrypt = simpleEncrypt;
        }

        @Override
        public String encrypt(String text) {
            return simpleEncrypt.encrypt(text,ENCRYPT_LENGTH);
        }

    }

    private static class SimpleEncrypt {
        public String encrypt(String text,int length) {
            return text + length;
        }
    }

}

对象适配器

在适配类中关联一共被适配者对象,通过调用被适配者对象的方法来实现适配。

类适配器

实现目标接口的同时,继承被适配者类。

接口适配器

通过一个抽象类来实现接口中的所有方法。具体类通过继承抽象类,根据需求只需要重写特定的方法。

表 适配器种类

1.2 优缺点

优点:

  1. 提高代码的复用性,让原本不兼容的类可以协同工作。
  2. 降低系统耦合度,客户端只与适配器进行交互。

缺点:

  1. 过度使用适配器可能导致系统变得复杂,难以理解和维护,也可能导致性能下降。

2 装饰模式

需求:1)想给给类添加新的功能。而不希望使用继承的方式。2)动态添加及撤销功能。

2.1 装饰模式介绍

在不改变一个对象的接口的前提下,通过创建一个装饰者来包裹真实对象,来动态地增加额外的职责到该对象

图 装饰模式 UML

完全透明

装饰对象和原始对象具有相同的接口,客户端不需要区分装饰对象及原始对象。

半透明

允许装饰对象的接口与原始对象的接口不完全一致。装饰对象的接口可能会比原始对象更宽,但仍需要实现原始对象的接口。

表 装饰模式的两种模式

public class DecoratorPattern {

    public static void main(String[] args) {
        String text = "hello decorator";
        Verifier noEmptyVerifier = new NoEmptyVerifier();
        Verifier minLengthVerifier = new MinLengthVerifier(noEmptyVerifier,7);
        System.out.println(minLengthVerifier.verification(text));
    }

    private interface Verifier {
        boolean verification(String text);
    }

    private static class NoEmptyVerifier implements Verifier {

        @Override
        public boolean verification(String text) {
            return text != null && text.trim().length() > 0;
        }
    }

    private static class MinLengthVerifier implements Verifier {

        private final int DEFAULT_MIN_LENGTH = 15;

        private final Verifier verifier;
        private int minLength = DEFAULT_MIN_LENGTH;

        private MinLengthVerifier(Verifier verifier) {
            this.verifier = verifier;
        }

        public MinLengthVerifier(Verifier verifier, int minLength) {
            this.verifier = verifier;
            this.minLength = minLength;
        }

        @Override
        public boolean verification(String text) {
            return verifier.verification(text) && text.length() > minLength;
        }
    }

}

2.2 优缺点

优点:

  1. 提供了比继承更多的灵活性。
  2. 可以创建一个功能更加强大的对象,通过对一个对象进行多次装饰。
  3. 可以动态的添加及撤销功能。

缺点:

  1. 会产生很多小对象,如果过度使用,可能会导致程序变得复杂且难以维护。
  2. 在某些情况下,调试和排查问题的难度增加。

3 外观模式

需求:与系统交互时,不想与系统的其他业务模块产生关联,希望与一个统一的角色进行交互。

3.1 外观模式介绍

客户端与系统的通信通过一个统一的外观角色进行。

图 外观模式 UML

public class FacadePattern {

    public static void main(String[] args) { // 客户端
        SystemController controller = SystemController.getInstance();
        System.out.println(controller.getUser("facade"));
    }

    private static class SystemController { // 对外的接口

        private static volatile SystemController instance;

        public static SystemController getInstance() {
            if (instance == null) {
                synchronized (SystemController.class) {
                    if (instance == null) {
                        UserService service = new UserService(new UserMapper());
                        instance = new SystemController(service);
                    }
                }
            }
            return instance;
        }

        private final UserService userService;

        private SystemController(UserService userService) {
            this.userService = userService;
        }

        public String getUser(String username) {
            return userService.getUser(username);
        }
    }

    private static class UserService {
        private final UserMapper userMapper;

        private UserService(UserMapper userMapper) {
            this.userMapper = userMapper;
        }

        public String getUser(String username) {
            if (username == null) return "";
            return userMapper.searcherByUsername(username);
        }

    }

    private static class UserMapper {
        public String searcherByUsername(String username) {
            return "用户+" + username;
        }
    }

}

3.2 优缺点

优点:

1)将客户端与系统内部模块分隔开,符合迪米特法则,降低了耦合度。

缺点:

1)不符合开闭原则。


网站公告

今日签到

点亮在社区的每一天
去签到