3W 学习法总结结构型模式(附 Java 代码实战及开源框架应用)
结构型模式 主要关注 类与对象的组合,确保不同组件之间能够高效协作,提高系统的灵活性和可维护性。本文采用 3W 学习法(What、Why、How),深入分析 七大结构型模式(适配器、桥接、装饰器、组合、外观、享元、代理),并结合 Java 代码实战 及 开源框架中的应用,帮助你高效掌握这些模式的实战技巧。
1. 适配器模式(Adapter)
✅ What:适配器模式是什么?
适配器模式 通过 转换接口 使原本不兼容的类能够一起工作。
🤔 Why:为什么要使用适配器模式?
- 解决接口不兼容问题,让新旧代码无缝衔接。
- 复用已有代码,避免修改原始代码。
🚀 How:如何实现适配器模式?(Java 代码实战)
// 目标接口
interface Target {void request();
}// 需要适配的类
class Adaptee {void specificRequest() {System.out.println("Adaptee 特定请求");}
}// 适配器
class Adapter implements Target {private Adaptee adaptee = new Adaptee();public void request() {adaptee.specificRequest();}
}// 客户端调用
public class AdapterDemo {public static void main(String[] args) {Target target = new Adapter();target.request(); // 输出: Adaptee 特定请求}
}
📌 在开源框架中的应用:
- Spring
HandlerAdapter
:适配不同类型的 Controller(如RequestMappingHandlerAdapter
)。 java.io.InputStreamReader
:将InputStream
适配为Reader
。
2. 桥接模式(Bridge)
✅ What:桥接模式是什么?
桥接模式 通过 分离抽象部分和实现部分,让它们可以独立变化。
🤔 Why:为什么要使用桥接模式?
- 降低耦合:抽象和实现独立演化,不受对方影响。
- 增强扩展性:适用于 多个维度变化 的场景。
🚀 How:如何实现桥接模式?(Java 代码实战)
// 实现接口
interface Implementor {void operationImpl();
}// 具体实现A
class ConcreteImplementorA implements Implementor {public void operationImpl() {System.out.println("具体实现A的操作");}
}// 抽象类
abstract class Abstraction {protected Implementor implementor;public Abstraction(Implementor implementor) {this.implementor = implementor;}abstract void operation();
}// 具体抽象类
class RefinedAbstraction extends Abstraction {public RefinedAbstraction(Implementor implementor) {super(implementor);}public void operation() {implementor.operationImpl();}
}// 客户端调用
public class BridgeDemo {public static void main(String[] args) {Implementor impl = new ConcreteImplementorA();Abstraction abstraction = new RefinedAbstraction(impl);abstraction.operation(); // 输出: 具体实现A的操作}
}
📌 在开源框架中的应用:
- JDBC 驱动:
java.sql.DriverManager
通过桥接不同数据库的驱动。 - Slf4j + Logback/Log4j:日志框架使用桥接模式适配不同日志实现。
3. 装饰器模式(Decorator)
✅ What:装饰器模式是什么?
装饰器模式 通过 动态添加新功能,而不修改原有对象。
🤔 Why:为什么要使用装饰器模式?
- 符合开闭原则:可扩展对象功能,避免修改原始代码。
- 支持功能叠加:适用于 多个额外行为 组合的场景。
🚀 How:如何实现装饰器模式?(Java 代码实战)
// 抽象组件
interface Component {void operation();
}// 具体组件
class ConcreteComponent implements Component {public void operation() {System.out.println("基本功能");}
}// 装饰器
abstract class Decorator implements Component {protected Component component;public Decorator(Component component) {this.component = component;}public void operation() {component.operation();}
}// 具体装饰器A
class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}public void operation() {super.operation();System.out.println("附加功能A");}
}// 客户端调用
public class DecoratorDemo {public static void main(String[] args) {Component component = new ConcreteDecoratorA(new ConcreteComponent());component.operation();// 输出:// 基本功能// 附加功能A}
}
📌 在开源框架中的应用:
- Spring
BeanPostProcessor
:可动态增强 Bean 的功能。 BufferedInputStream
:装饰InputStream
,提供缓冲能力。
4. 组合模式(Composite)
✅ What:组合模式是什么?
组合模式 允许 树形结构的对象 统一处理。
🤔 Why:为什么要使用组合模式?
- 统一对象处理方式:无论是单个对象还是组合对象,均可一致调用。
- 适用于层级结构:如 文件系统、组织架构 等。
🚀 How:如何实现组合模式?(Java 代码实战)
// 抽象组件
interface Component {void operation();
}// 叶子节点
class Leaf implements Component {public void operation() {System.out.println("执行叶子节点操作");}
}// 组合节点
class Composite implements Component {private List<Component> children = new ArrayList<>();public void add(Component component) {children.add(component);}public void operation() {for (Component child : children) {child.operation();}}
}// 客户端调用
public class CompositeDemo {public static void main(String[] args) {Composite root = new Composite();root.add(new Leaf());root.add(new Leaf());Composite branch = new Composite();branch.add(new Leaf());root.add(branch);root.operation();}
}
📌 在开源框架中的应用:
- Spring Security:权限规则采用组合模式组织权限节点。
- GUI 组件:Swing 的
JComponent
使用组合模式。
确实,结构型模式共有 7 种,前面只介绍了 4 种,缺少了 外观模式(Facade)、享元模式(Flyweight)、代理模式(Proxy)。下面继续补充它们的 3W 学习法解析、Java 实战代码及在开源框架中的应用。
5. 外观模式(Facade)
✅ What:外观模式是什么?
外观模式(Facade) 通过 提供一个统一的接口,简化子系统的复杂操作,降低系统耦合性。
🤔 Why:为什么要使用外观模式?
- 降低复杂性,隐藏子系统细节,使调用者只需与一个简单接口交互。
- 解耦代码,避免高层代码直接依赖多个复杂子系统。
🚀 How:如何实现外观模式?(Java 代码实战)
// 子系统A
class SubsystemA {void operationA() {System.out.println("子系统 A 操作");}
}// 子系统B
class SubsystemB {void operationB() {System.out.println("子系统 B 操作");}
}// 外观类(Facade)
class Facade {private SubsystemA subsystemA = new SubsystemA();private SubsystemB subsystemB = new SubsystemB();void operation() {subsystemA.operationA();subsystemB.operationB();}
}// 客户端调用
public class FacadeDemo {public static void main(String[] args) {Facade facade = new Facade();facade.operation();// 输出:// 子系统 A 操作// 子系统 B 操作}
}
📌 在开源框架中的应用:
- Spring
JdbcTemplate
:封装了数据库操作,简化 JDBC 使用。 HttpClient
:简化底层 HTTP 请求的复杂性。
6. 享元模式(Flyweight)
✅ What:享元模式是什么?
享元模式(Flyweight) 通过 共享对象 来减少内存占用,提高性能。
🤔 Why:为什么要使用享元模式?
- 减少内存开销,适用于 大量相似对象 场景。
- 提升系统性能,避免重复创建对象。
🚀 How:如何实现享元模式?(Java 代码实战)
import java.util.HashMap;
import java.util.Map;// 享元接口
interface Flyweight {void operation(String extrinsicState);
}// 具体享元
class ConcreteFlyweight implements Flyweight {private final String intrinsicState;ConcreteFlyweight(String intrinsicState) {this.intrinsicState = intrinsicState;}public void operation(String extrinsicState) {System.out.println("享元对象:" + intrinsicState + ",外部状态:" + extrinsicState);}
}// 享元工厂
class FlyweightFactory {private static final Map<String, Flyweight> pool = new HashMap<>();static Flyweight getFlyweight(String key) {if (!pool.containsKey(key)) {pool.put(key, new ConcreteFlyweight(key));}return pool.get(key);}
}// 客户端调用
public class FlyweightDemo {public static void main(String[] args) {Flyweight fw1 = FlyweightFactory.getFlyweight("A");Flyweight fw2 = FlyweightFactory.getFlyweight("A");Flyweight fw3 = FlyweightFactory.getFlyweight("B");fw1.operation("X");fw2.operation("Y");fw3.operation("Z");System.out.println(fw1 == fw2); // 输出: true(共享同一个对象)}
}
📌 在开源框架中的应用:
Integer.valueOf(int)
:JDK 享元模式,缓存-128 ~ 127
的 Integer 对象。- 线程池(Thread Pool):复用线程对象,减少资源消耗。
7. 代理模式(Proxy)
✅ What:代理模式是什么?
代理模式(Proxy) 通过 控制访问目标对象,增加额外行为(如权限控制、懒加载、缓存等)。
🤔 Why:为什么要使用代理模式?
- 增强功能(如日志、事务、权限)。
- 控制对象访问(如远程代理、虚拟代理)。
🚀 How:如何实现代理模式?(Java 代码实战)
静态代理
// 接口
interface Service {void operation();
}// 真实对象
class RealService implements Service {public void operation() {System.out.println("真实业务逻辑");}
}// 代理类
class ProxyService implements Service {private RealService realService = new RealService();public void operation() {System.out.println("前置增强逻辑");realService.operation();System.out.println("后置增强逻辑");}
}// 客户端调用
public class StaticProxyDemo {public static void main(String[] args) {Service service = new ProxyService();service.operation();// 输出:// 前置增强逻辑// 真实业务逻辑// 后置增强逻辑}
}
动态代理(JDK 动态代理)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 动态代理处理器
class DynamicProxyHandler implements InvocationHandler {private Object target;DynamicProxyHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("前置增强逻辑");Object result = method.invoke(target, args);System.out.println("后置增强逻辑");return result;}
}// 客户端调用
public class DynamicProxyDemo {public static void main(String[] args) {Service realService = new RealService();Service proxy = (Service) Proxy.newProxyInstance(realService.getClass().getClassLoader(),realService.getClass().getInterfaces(),new DynamicProxyHandler(realService));proxy.operation();// 输出:// 前置增强逻辑// 真实业务逻辑// 后置增强逻辑}
}
📌 在开源框架中的应用:
- Spring AOP:代理模式增强 Bean 功能,如事务、日志、权限控制。
- MyBatis Mapper:动态代理生成 SQL 查询接口的实现类。
总结
设计模式 | 主要作用 | 适用场景 |
---|---|---|
适配器模式 | 让不兼容的接口协同工作 | HandlerAdapter 、InputStreamReader |
桥接模式 | 分离抽象和实现,解耦 | JDBC 驱动、日志框架 |
装饰器模式 | 动态增强对象功能 | BufferedInputStream 、BeanPostProcessor |
组合模式 | 统一树形结构处理 | Spring Security 权限管理、GUI 组件 |
外观模式 | 简化系统调用 | JdbcTemplate 、HttpClient |
享元模式 | 共享对象减少内存消耗 | Integer.valueOf(int) 、线程池 |
代理模式 | 控制访问目标对象,增强功能 | AOP、MyBatis 动态代理 |
掌握这 7 大结构型模式,让你的代码 更清晰、可扩展、性能更优!🚀