结构型设计模式是用于设计对象和类之间关系的一组设计模式。一共有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 优缺点
优点:
- 提高代码的复用性,让原本不兼容的类可以协同工作。
- 降低系统耦合度,客户端只与适配器进行交互。
缺点:
- 过度使用适配器可能导致系统变得复杂,难以理解和维护,也可能导致性能下降。
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 优缺点
优点:
- 提供了比继承更多的灵活性。
- 可以创建一个功能更加强大的对象,通过对一个对象进行多次装饰。
- 可以动态的添加及撤销功能。
缺点:
- 会产生很多小对象,如果过度使用,可能会导致程序变得复杂且难以维护。
- 在某些情况下,调试和排查问题的难度增加。
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)不符合开闭原则。