????????設計模式是一套被反復使用的、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是為了重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。設計模式使代碼編制真正工程化,設計模式是軟件工程的基石,如同大廈的一塊塊磚石一樣,項目中合理地運用設計模式可以完美地解決很多問題。
? ? ? ? 設計模式多種多樣,這里參考設計模式簡介,本篇主要介紹最常用的幾種。
設計模式的分類
分類 | 核心目標 | 典型模式 |
---|---|---|
創建型模式 | 對象創建過程的抽象與優化 | 工廠模式、抽象工廠、單例、建造者、原型 |
結構型模式 | 對象與類的組織方式(組合結構優化) | 適配器、代理、裝飾者、橋接、組合、外觀、享元 |
行為型模式 | 對象間的交互與職責分配(通信流程優化) | 策略、觀察者、責任鏈、模板方法、命令、狀態、迭代器、中介者、備忘錄、訪問者 |
常用的設計模式
單例模式
????????單例模式(Singleton Pattern)是一種創建型設計模式,其核心目標是確保一個類僅有一個實例,并提供該實例的全局訪問點。
????????特點:1.單例類只有一個實例對象。
? ? ? ? ? ? ? ? ? ?2.單例對象必須由單例類創建。
? ? ? ? ? ? ? ? ? ?3.對外提供一個訪問該單例的全局訪問點
核心實現方式
1. 餓漢式
-
特點:類加載時立即創建實例,線程安全但可能造成資源浪費。
public class EagerSingleton {// 類加載時初始化實例private static final EagerSingleton instance = new EagerSingleton();// 私有構造方法,防止外部實例化private EagerSingleton() {}public static EagerSingleton getInstance() {return instance;} }
2. 懶漢式
-
特點:延遲實例化,首次調用時創建對象,需處理多線程安全問題。
基礎版(非線程安全):
public class LazySingleton {private static LazySingleton instance;private LazySingleton() {}public static LazySingleton getInstance() {if (instance == null) {instance = new LazySingleton();}return instance;}
}
?同步方法版(線程安全但性能低):
public class SynchronizedSingleton {private static SynchronizedSingleton instance;private SynchronizedSingleton() {}public static synchronized SynchronizedSingleton getInstance() {if (instance == null) {instance = new SynchronizedSingleton();}return instance;}
}
3. 雙重檢查鎖(Double-Checked Locking)?
-
特點:延遲加載 + 線程安全 + 高性能,適用于多線程環境。
public class DCLSingleton {// 使用 volatile 防止指令重排序private static volatile DCLSingleton instance;private DCLSingleton() {}public static DCLSingleton getInstance() {if (instance == null) { // 第一次檢查synchronized (DCLSingleton.class) { // 同步塊if (instance == null) { // 第二次檢查instance = new DCLSingleton();}}}return instance;}
}
舉例:Runtime類
public class Runtime {private static Runtime currentRuntime = new Runtime();public static Runtime getRuntime() {return currentRuntime;}private Runtime() {}
}
?jdk中提供的類,標準的單例模式應用。
工廠模式
????????工廠模式(Factory Pattern)是一種創建型設計模式,其核心思想是將對象的創建邏輯與使用邏輯分離,通過統一的工廠接口或類來實例化對象,從而降低代碼耦合度并提升擴展性。
一、簡單工廠模式
定義
-
核心:通過一個工廠類,根據傳入的參數決定創建哪種具體產品對象。
-
適用場景:產品種類較少且創建邏輯簡單。
// 1. 定義產品接口
interface Car {void drive();
}// 2. 具體產品實現
class SedanCar implements Car {@Overridepublic void drive() {System.out.println("駕駛轎車");}
}class SUVCar implements Car {@Overridepublic void drive() {System.out.println("駕駛SUV");}
}// 3. 簡單工廠類
class CarFactory {public static Car createCar(String type) {switch (type.toLowerCase()) {case "sedan":return new SedanCar();case "suv":return new SUVCar();default:throw new IllegalArgumentException("未知的汽車類型");}}
}// 4. 使用示例
public class Client {public static void main(String[] args) {Car sedan = CarFactory.createCar("sedan");sedan.drive(); // 輸出:駕駛轎車Car suv = CarFactory.createCar("suv");suv.drive(); // 輸出:駕駛SUV}
}
二、工廠方法模式
定義
-
核心:定義抽象工廠接口,由子類決定具體實例化哪個類。每個產品對應一個工廠。
public interface Car {void run();
}public class Aodi implements Car {@Overridepublic void run() {System.out.println("奧迪汽車行駛");}
}public class Bmw implements Car {@Overridepublic void run() {System.out.println("寶馬汽車行駛");}
}public interface CarFactory {Car createCar();
}public class AodiFactory implements CarFactory{@Overridepublic Car createCar() {return new Aodi();}
}public class BmwFactory implements CarFactory{@Overridepublic Car createCar() {return new Bmw();}
}public class Test {public static void main(String[] args) {CarFactory aodicarFactory = new AodiFactory();Car aodi = aodicarFactory.createCar();aodi.run();CarFactory bmwcarFactory = new BmwFactory();Car bmw = bmwcarFactory.createCar();bmw.run();}
}
?一個產品對應一個工廠,奧迪車對應奧迪工廠,寶馬車對應寶馬工廠。
三、抽象工廠模式
定義
-
核心:提供一個接口,用于創建相關或依賴對象的家族,而無需指定具體類。
public interface AbstractFactory {Car getCar();Phone getPhone();
}public interface Car {void run();
}public interface Phone {void call();
}public class AodiFactory implements AbstractFactory{@Overridepublic Car getCar() {return new AodiCar();}@Overridepublic Phone getPhone() {return new AodiPhone();}
}public class AodiCar implements Car{@Overridepublic void run() {System.out.println("奧迪汽車行駛");}
}public class AodiPhone implements Phone{@Overridepublic void call() {System.out.println("奧迪手機打電話");}
}public class BmwFactory implements AbstractFactory{@Overridepublic Car getCar() {return new BmwCar();}@Overridepublic Phone getPhone() {return new BmwPhone();}
}public class BmwCar implements Car{@Overridepublic void run() {System.out.println("寶馬汽車行駛");}
}public class BmwPhone implements Phone {@Overridepublic void call() {System.out.println("寶馬手機打電話");}
}public class Test {public static void main(String[] args) {AbstractFactory aodiFactory = new AodiFactory();Car aodiCar = aodiFactory.getCar();Phone aodiphone = aodiFactory.getPhone();aodiCar.run();aodiphone.call();AbstractFactory bmwFactory = new BmwFactory();Car bmwCar = bmwFactory.getCar();Phone bmwPhone = bmwFactory.getPhone();bmwCar.run();bmwPhone.call();}
}
?一個接口對應一個家族或者一個系列的東西,在這個案例中,就是奧迪工廠對應奧迪手機,奧迪車等等,寶馬抽象工廠對應寶馬手機和寶馬車。
三種工廠模式對比
模式 | 核心區別 | 適用場景 |
---|---|---|
簡單工廠 | 一個工廠類創建所有產品 | 產品類型少,邏輯簡單 |
工廠方法 | 每個產品對應一個工廠類 | 需要靈活擴展產品類型 |
抽象工廠 | 創建多個相關產品組成的家族 | 需要保證產品族的兼容性 |
原型模式
????????原型模式(Prototype Pattern)是一種創建型設計模式,其核心思想是通過復制現有對象來創建新對象,而不是通過?new
?關鍵字重新構造。
復制對象及其所有引用類型字段,創建完全獨立的新對象。
class Address implements Cloneable {String city;public Address(String city) {this.city = city;}@Overridepublic Address clone() throws CloneNotSupportedException {return (Address) super.clone();}
}class User implements Cloneable {String name;Address address;public User(String name, Address address) {this.name = name;this.address = address;}// 深拷貝:遞歸復制引用類型字段@Overridepublic User clone() throws CloneNotSupportedException {User cloned = (User) super.clone();cloned.address = this.address.clone(); // 克隆Address對象return cloned;}
}// 使用示例
User user1 = new User("Alice", new Address("Beijing"));
User user2 = user1.clone();user2.address.city = "Shanghai";
System.out.println(user1.address.city); // 輸出:Beijing(原對象未受影響)
優點 | 缺點 |
---|---|
提升性能,避免重復初始化 | 深拷貝實現復雜(需遞歸克隆所有引用對象) |
動態配置對象屬性 | 需注意循環引用問題 |
繞過構造函數限制 | 對不支持克隆的類需額外處理(如實現接口) |
小結:原型模式通過復制現有對象高效創建新實例,尤其適用于對象初始化成本高或需要動態配置的場景。在實現時需注意?深拷貝與淺拷貝?的區別,避免因引用共享導致的數據不一致。合理使用原型模式,可以顯著優化性能并簡化復雜對象的創建邏輯。?
代理模式
????????代理模式(Proxy Pattern)是一種結構型設計模式,其核心思想是通過代理對象控制對原始對象的訪問,在不修改原始類的前提下增強功能或限制訪問。
代理模式的三種角色
-
抽象主題
定義真實主題和代理主題的公共接口 -
真實主題
實現業務邏輯的核心類 -
代理類
持有真實主題的引用,控制對真實主題的訪問,并附加額外功能。
靜態代理
手動編寫代理類,代理類與真實類實現同一接口。
// 1. 抽象主題接口
interface UserService {void saveUser(String username);
}// 2. 真實主題
class UserServiceImpl implements UserService {public void saveUser(String username) {System.out.println("保存用戶: " + username);}
}// 3. 靜態代理類
class UserServiceProxy implements UserService {private UserService target;public UserServiceProxy(UserService target) {this.target = target;}public void saveUser(String username) {//通知System.out.println("[日志] 開始保存用戶...");target.saveUser(username);//通知System.out.println("[日志] 用戶保存完成");}
}// 使用示例
public class Client {public static void main(String[] args) {UserService realService = new UserServiceImpl();UserService proxy = new UserServiceProxy(realService);proxy.saveUser("Alice");}
}
?????????一個代理類可以對某一類的目標提供代理
????????滿足開閉原則(添加一類目標時,可以擴展添加一個新的代理類),
????????代碼是寫死的,不靈活
動態代理
?jdk代理
? ? ? ? 創建一個代理對象生成器,實現InvocationHandler,重寫invoke方法,這個方法會被代理對象動態調用,代理對象在運行時,被動態創建,可以代理任意的目標對象,提高靈活性。
? ? ? ? 注意被代理的目標對象,必須實現一個接口,在生成代理對象時,需要通過接口來獲取目標對象信息。
? ? ? ? 底層實現原理利用反射機制。
/*抽象操作定義 賣東西*/
public interface Sell {void sell();
}//目標類
public class CarFactoryImpl implements Sell {@Overridepublic void sell() {System.out.println("汽車廠賣汽車");}}/*動態代理類代理類不需要實現與目標類相同的接口,這樣就可以代理任意的目標類但是是有要求的,目標類必需實現接口,此種方式是動態代理的實現方式之一: jdk代理 是一種純反射機制實現(動態獲取目標類接口方法)*/
public class DynamicProxy implements InvocationHandler {Object object;//真實對象,接收任何的目標類對象public DynamicProxy(Object object) {this.object = object;}/*在代理類中調用目標類中的具體方法,動態的將代理動態對象,目標類中要調用的方法,及方法中的參數傳遞過來Method method 就是動態獲取的真正要執行的方法*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("之前開啟事務");method.invoke(object);System.out.println("之后提交事務");return proxy;}public Object getProxy(){return Proxy.newProxyInstance(object.getClass().getClassLoader(),object.getClass().getInterfaces(),this);}
}public class Test {public static void main(String[] args) {CarFactoryImpl vip = new CarFactoryImpl();DynamicProxy dtproxy = new DynamicProxy(vip);//自己創建的代理類對象//這才是真正的創建動態代理對象 獲取目標類所實現的接口Sell carfactory = (Sell)dtproxy.getProxy();carfactory.sell();//使用代理對象調用接口中的方法,獲取當前調用的方法,最終調用invoke方法}
}
cglib代理
????????CGLib 采用了非常底層的字節碼技術,其原理是通過字節碼技術為一個類創建子類,并在子類中采用方法攔截的技術攔截所有父類方法的調用,順勢織入橫切邏輯。
public class CarFactoryImpl {public void sell() {System.out.println("汽車廠賣汽車");}}import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/** 動態代理類*/
public class CGLibProxy implements MethodInterceptor {private Enhancer enhancer = new Enhancer();public Object getProxy(Class<?> clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /** 攔截所有目標類方法的調用 * 參數: * obj 目標實例對象 * method 目標方法的反射對象 * args 方法的參數 * proxy 代理類的實例 */public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {//代理類調用父類的方法 System.out.println("開始事務"); Object result = proxy.invokeSuper(obj, args); System.out.println("關閉事務"); return result; }
}
public class Test {public static void main(String[] args) {CGLibProxy proxy = new CGLibProxy();CarFactoryImpl carFactory = (CarFactoryImpl) proxy.getProxy(CarFactoryImpl.class);carFactory.sell();}
}
????????要求目標類不能是final修飾,方法也不能是final修飾的,和static修飾的.?
????????在spring框架中兩種代理生成機制都實現了:
????????????????可以根據目標是否實現接口自動選擇生成代理對象的方式,
????????????????默認采用cglib代理方式生成.?
代理模式通過間接訪問目標對象,實現了功能增強和訪問控制,是解耦系統模塊、提升靈活性的重要手段。選擇代理類型時需注意:
-
靜態代理:簡單場景,代理類少。
-
JDK 動態代理:基于接口,適合代理多個方法。
-
CGLIB 代理:代理無接口的類,需注意性能與限制。
適配器模式
????????適配器模式(Adapter Pattern)是一種結構型設計模式,用于將不兼容的接口轉換為客戶端期望的接口,使得原本無法協同工作的類能夠一起協作。其核心思想是通過一個“中間層”(適配器)解決接口不匹配問題,類似于現實中的電源轉接頭。
適配器模式的核心角色?
角色 | 說明 |
---|---|
目標接口(Target) | 客戶端期望的接口(如?XmlParser ),定義客戶端調用的標準方法。 |
適配者(Adaptee) | 已存在的、需要被適配的接口或類(如?JsonParser ),提供實際功能但接口不兼容。 |
適配器(Adapter) | 實現目標接口,并持有適配者的引用,通過轉換邏輯調用適配者的方法。 |
-
特點:通過組合持有適配者對象,更靈活且符合合成復用原則。
-
適用場景:適配者與目標接口差異較大,或需適配多個適配者。
// 目標接口
public interface XmlParser {void parseXml(String xml);
}// 適配者類
public class JsonParser {public void parseJson(String json) {System.out.println("解析JSON: " + json);}
}// 對象適配器(持有適配者引用,實現目標接口)
public class JsonToXmlAdapter implements XmlParser {private JsonParser jsonParser;public JsonToXmlAdapter(JsonParser jsonParser) {this.jsonParser = jsonParser;}public void parseXml(String xml) {String json = convertXmlToJson(xml); // 轉換邏輯jsonParser.parseJson(json); // 調用適配者方法}private String convertXmlToJson(String xml) {//偽代碼return "Json"+xml,}
}
?測試
public class Test {public static void main(String[] args) {JsonParser jsonParser = new JsonParser();XmlParser xmlParser = new JsonToXmlAdapter(jsonParser);xmlParser.parseXml("<order id='123'/>"); // 輸出:解析JSON: { ... }}
}
其他案例:
Java I/O 中的適配器:將字節流轉換為字符流。
Spring MVC 的 HandlerAdapter:統一處理不同類型的控制器(如基于注解的?@Controller
?和舊的?Controller
?接口)。
小結:
適配器模式通過接口轉換解決不兼容問題,是集成遺留代碼或第三方庫的利器。
使用建議:
-
優先選擇對象適配器,更靈活且符合組合復用原則。
-
避免濫用適配器,若接口不匹配問題可通過重構解決,則無需引入適配器。
-
在框架設計、系統集成、多格式兼容等場景中,適配器模式能顯著提升代碼復用性和擴展性。
模版方法模式
??????模板方法模式(Template Method Pattern)是一種行為型設計模式,其核心思想是定義一個算法的骨架,將某些步驟延遲到子類實現,使得子類可以在不改變算法結構的情況下重新定義某些步驟的具體實現。
角色 | 說明 |
---|---|
抽象類(Abstract Class) | 定義算法的骨架(模板方法),包含具體步驟和抽象方法。 |
具體子類(Concrete Class) | 實現抽象類中的抽象方法,完成特定步驟的具體邏輯。 |
模板方法(Template Method) | 抽象類中定義的算法流程,通常為?final ?方法,防止子類重寫算法結構。 |
鉤子方法(Hook Method) | 抽象類中可選的方法,子類可選擇性覆蓋,用于影響算法流程。 |
舉個例子:客戶去銀行辦事,一般要經過以下 4 個流程:取號、排隊、辦理具體業務、對銀行工作人員進行評分等。但是去辦理的業務可能不同,可以延遲到子類中實現。
public abstract class AbstractBank {//辦理業務方法 -- 模板方法public void handle(){this.offerNumber();this.lineup();this.business();this.score();}//抽號public void offerNumber(){System.out.println("抽號");}//排隊public void lineup(){System.out.println("排隊");}//辦理具體業務--抽象方法,由具體子類實現public abstract void business();//評分public void score(){System.out.println("評分");}
}/*轉賬業務類*/
public class TransferBusiness extends AbstractBank{//轉賬public void business() {System.out.println("我要轉賬");}}/*存錢業務*/
public class StoreBusiness extends AbstractBank{//辦理的具體業務public void business() {System.out.println("我要存錢");}
}
public class Test {public static void main(String[] args) {StoreBusiness storeBusiness = new StoreBusiness();storeBusiness.handle();System.out.println("===================================");TransferBusiness transferBusiness = new TransferBusiness();transferBusiness.handle();}
}
其他案例:
Servlet 的生命周期
????????Servlet 的?service()
?方法是一個模板方法,處理 HTTP 請求的通用流程,子類(如?HttpServlet
)通過重寫?doGet()
、doPost()
?實現具體邏輯。
小潔:
模板方法模式通過固定算法骨架和靈活步驟實現,在保證代碼復用性的同時支持擴展。其關鍵點在于:
-
定義模板方法:使用?
final
?修飾確保算法結構不被破壞。 -
抽象步驟方法:子類必須實現差異邏輯。
-
鉤子方法:提供可選擴展點,控制算法流程。
適用場景:
-
多個子類有共同行為,但部分步驟不同。
-
需要控制子類擴展方式,避免破壞核心流程。
注意事項:
-
避免過度使用繼承,若算法步驟頻繁變化,可考慮策略模式。
-
合理使用鉤子方法,保持代碼簡潔。
策略模式
????????策略模式(Strategy Pattern)是一種行為型設計模式,其核心思想是定義一系列算法,封裝每個算法,并使它們可以互相替換。策略模式讓算法的變化獨立于使用它的客戶端,通過動態切換算法實現靈活擴展,同時遵循開閉原則(對擴展開放,對修改關閉)。
角色 | 說明 |
---|---|
策略接口(Strategy) | 定義算法的公共接口(如?PaymentStrategy ),所有具體策略必須實現該接口。 |
具體策略類(Concrete Strategy) | 實現策略接口,提供具體的算法實現(如支付寶支付、微信支付)。 |
上下文類(Context) | 持有策略對象,并委托具體策略執行算法(如訂單支付處理類)。 |
?案例:電商支付策略
//定義策略接口
interface PaymentStrategy {void pay(double amount);
}//實現具體策略類// 支付寶支付
class AlipayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("支付寶支付: " + amount + "元");}
}// 微信支付
class WechatPayStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("微信支付: " + amount + "元");}
}//委托策略執行// 銀行卡支付
class BankCardStrategy implements PaymentStrategy {@Overridepublic void pay(double amount) {System.out.println("銀行卡支付: " + amount + "元");}
}class OrderPayment {private PaymentStrategy paymentStrategy;// 設置支付策略public void setPaymentStrategy(PaymentStrategy paymentStrategy) {this.paymentStrategy = paymentStrategy;}// 執行支付public void executePayment(double amount) {if (paymentStrategy == null) {throw new IllegalStateException("未設置支付策略");}paymentStrategy.pay(amount);}
}//調用
public class Client {public static void main(String[] args) {OrderPayment order = new OrderPayment();// 使用支付寶支付order.setPaymentStrategy(new AlipayStrategy());order.executePayment(100.0); // 輸出:支付寶支付: 100.0元// 切換為微信支付order.setPaymentStrategy(new WechatPayStrategy());order.executePayment(200.0); // 輸出:微信支付: 200.0元}
}
總結
策略模式通過封裝算法和動態切換策略,有效提升了系統的靈活性和可維護性。其核心優勢在于:
-
解耦算法與業務邏輯:客戶端僅依賴抽象策略接口。
-
簡化單元測試:每個策略可獨立測試。
-
符合開閉原則:新增策略無需修改現有代碼。
適用場景:
-
系統需要多種算法變體,且需動態切換。
-
存在復雜條件分支,需消除大量?
if-else
?或?switch
?語句。 -
算法需要獨立復用,或需隔離算法實現細節。
注意事項:
-
合理控制策略類數量,避免類膨脹。
-
優先使用組合而非繼承,保持代碼靈活性。
觀察者模式
????????觀察者模式(Observer Pattern)是一種行為型設計模式,用于建立對象間的一對多依賴關系,當一個對象(被觀察者)的狀態發生改變時,所有依賴它的對象(觀察者)會自動收到通知并更新。
角色 | 說明 |
---|---|
被觀察者(Subject) | 維護觀察者列表,提供注冊、注銷和通知方法(如?addObserver() ,?notifyObservers() )。 |
觀察者(Observer) | 定義更新接口(如?update() ),接收被觀察者的狀態變化通知。 |
具體被觀察者(Concrete Subject) | 實現業務邏輯,狀態變更時觸發通知(如訂單狀態變化)。 |
具體觀察者(Concrete Observer) | 實現?update() ?方法,定義收到通知后的具體響應邏輯(如發送郵件、更新UI)。 |
案例:微信公眾號發文,用戶訂閱
//抽象觀察者
public interface Observer {void update(String message);}//抽象主題
public interface Subject {//增加訂閱者public void attach(Observer observer);//刪除訂閱者public void detach(Observer observer);//通知訂閱者更新消息public void notify(String message);
}//真實主體
public class SubscriptionSubject implements Subject {//儲存訂閱公眾號的微信用戶--觀察者private List<Observer> weixinUserlist = new ArrayList();//增加訂閱者@Overridepublic void attach(Observer observer) {weixinUserlist.add(observer);}//刪除訂閱者@Overridepublic void detach(Observer observer) {weixinUserlist.remove(observer);}//通知訂閱者更新消息@Overridepublic void notify(String message) {for (Observer observer : weixinUserlist) {observer.update(message);}}
}//真實觀察者
public class WeixinUser implements Observer{// 微信用戶名private String name;public WeixinUser(String name) {this.name = name;}@Overridepublic void update(String message) {System.out.println(name + "-" + message);}}
調用
public class Test {public static void main(String[] args) {SubscriptionSubject mSubscriptionSubject=new SubscriptionSubject();//創建微信用戶WeixinUser user1=new WeixinUser("張三");WeixinUser user2=new WeixinUser("李四");WeixinUser user3=new WeixinUser("王麻子");//訂閱公眾號mSubscriptionSubject.attach(user1);mSubscriptionSubject.attach(user2);mSubscriptionSubject.attach(user3);//公眾號更新發出消息給訂閱的微信用戶mSubscriptionSubject.notify("文章更新了");}}
?總結
觀察者模式通過事件通知機制實現對象間的動態聯動,是解耦復雜系統的有效工具。其核心價值在于:
-
松耦合設計:主題與觀察者獨立演化。
-
靈活擴展:動態增刪觀察者,無需修改主題。
-
事件驅動:支持實時響應和異步處理。
適用場景:
-
需要實現一對多的消息通知。
-
期望降低對象間的直接依賴。
-
需構建靈活、可擴展的事件處理系統。
注意事項:
-
控制通知頻率,避免性能瓶頸。
-
合理處理異常,防止單個觀察者失敗影響整體流程。
-
結合具體需求選擇同步或異步通知方式。
推薦小說:大話設計模式