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 大結構型模式,讓你的代碼 更清晰、可擴展、性能更優!🚀