JavaScript 因其廣泛采用和多功能性,已成為現(xiàn)代 Web 開發(fā)的基石。隨著您深入研究 JavaScript 開發(fā),理解和利用模式變得至關(guān)重要。在本文中,我們將踏上揭開 JavaScript 模式的神秘面紗的旅程,并探討它們?nèi)绾卧鰪?qiáng)您的編碼實(shí)踐。
先決條件
要理解本文中討論的概念和技術(shù),您應(yīng)該了解 JavaScript 的基礎(chǔ)知識。熟悉變量、函數(shù)、數(shù)據(jù)類型、面向?qū)ο缶幊痰雀拍钪陵P(guān)重要。
在繼續(xù)之前,讓我們花點(diǎn)時(shí)間來了解 JavaScript 作為一種編程語言的重要性。
JavaScript 作為一種編程語言
JavaScript,通常被稱為“網(wǎng)絡(luò)語言”,是一種動(dòng)態(tài)的高級編程語言。它主要用于網(wǎng)絡(luò)瀏覽器中的客戶端腳本,但隨著 Node.js 的出現(xiàn),它在服務(wù)器端也獲得了關(guān)注。JavaScript 的主要功能包括操縱 DOM、處理事件、為網(wǎng)頁提供交互性等。
話雖如此,讓我們簡要討論一下 JavaScript 中模式的重要性及其目的。
JavaScript 開發(fā)中模式的重要性
JavaScript 中的模式是針對軟件開發(fā)過程中遇到的反復(fù)出現(xiàn)的問題的經(jīng)過驗(yàn)證的解決方案。它們提供結(jié)構(gòu)、改進(jìn)代碼組織、增強(qiáng)可維護(hù)性并促進(jìn)可重用性。通過理解和應(yīng)用模式,開發(fā)人員可以編寫更簡潔、更高效的代碼,并有效地應(yīng)對復(fù)雜的挑戰(zhàn)。
理解 JavaScript 模式的目的
理解 JavaScript 模式不僅僅是記住語法或遵循最佳實(shí)踐。它使開發(fā)人員能夠批判性地思考軟件設(shè)計(jì),選擇合適的解決方案并構(gòu)建可擴(kuò)展的應(yīng)用程序。通過掌握 JavaScript 模式,您可以深入了解該語言及其生態(tài)系統(tǒng),從而編寫出健壯且可維護(hù)的代碼。
既然我們知道了 JavaScript 模式的重要性及其目的,那么讓我們深入了解 JS 設(shè)計(jì)模式的基礎(chǔ)知識。
設(shè)計(jì)模式的基礎(chǔ)知識
在本節(jié)中,我們?yōu)槔斫?JavaScript 開發(fā)中的設(shè)計(jì)模式奠定基礎(chǔ)。
設(shè)計(jì)模式的定義和特征
設(shè)計(jì)模式是可重用的模板,它封裝了解決反復(fù)出現(xiàn)的軟件設(shè)計(jì)問題的最佳實(shí)踐。它們提供了一種設(shè)計(jì)軟件系統(tǒng)并促進(jìn)模塊化、靈活且可維護(hù)代碼的結(jié)構(gòu)化方法。設(shè)計(jì)模式的共同特征包括其目的、結(jié)構(gòu)、參與者和協(xié)作。
設(shè)計(jì)模式的類型
設(shè)計(jì)模式可以分為三大類:
-
創(chuàng)建型
-
結(jié)構(gòu)型
-
行為
了解這些類別有助于確定給定問題的適當(dāng)模式。
- 創(chuàng)建型模式
創(chuàng)建型模式專注于對象創(chuàng)建機(jī)制,提供以靈活和可控的方式實(shí)例化對象的方法。JavaScript 中一些常用的創(chuàng)建型模式包括:
-
單例
-
工廠
-
構(gòu)造函數(shù)
-
原型
-
生成器
-
模塊
單例模式
單例模式確保一個(gè)類只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)。當(dāng)您想限制類的實(shí)例數(shù)量并確保整個(gè)應(yīng)用程序中都可以訪問單個(gè)共享實(shí)例時(shí),此模式非常有用。
// Implementation example of the Singleton Pattern
class Singleton {
constructor() {
if (!Singleton.instance) {
// Initialize the instance
Singleton.instance = this;
}
return Singleton.instance;
}
}
const instance1 = new Singleton();
const instance2 = new Singleton();
console.log(instance1 === instance2); // Output: true
在此示例中,Singleton 類有一個(gè)構(gòu)造函數(shù),用于檢查該類的實(shí)例是否已存在。如果實(shí)例不存在( !Singleton.instance
條件),它將通過將 this 分配給 Singleton.instance
來初始化實(shí)例。這確保對構(gòu)造函數(shù)的后續(xù)調(diào)用將返回相同的實(shí)例。
使用 new Singleton() 語法創(chuàng)建 instance1 和 instance2 時(shí),這兩個(gè)變量都引用 Singleton 類的同一個(gè)實(shí)例。因此,使用嚴(yán)格相等運(yùn)算符比較 instance1 === instance2 時(shí),它將計(jì)算為 true。
工廠模式
工廠模式提供了一種創(chuàng)建對象而無需指定其具體類的方法。它將對象創(chuàng)建邏輯封裝在一個(gè)單獨(dú)的工廠方法中,從而允許創(chuàng)建者和創(chuàng)建的對象之間具有靈活性和解耦。
// Implementation example of the Factory Pattern
class Car {
constructor(make, model) {
this.make = make;
this.model = model;
}
}
class CarFactory {
createCar(make, model) {
return new Car(make, model);
}
}
const factory = new CarFactory();
const myCar = factory.createCar("Tope", "Model 1");
在此示例中,使用 new CarFactory()
創(chuàng)建 CarFactory
實(shí)例,然后使用參數(shù)“Tope”和“Model 1”對工廠調(diào)用 createCar
方法。這會(huì)創(chuàng)建一個(gè)新的汽車對象,其品牌為“Tope”,型號為“Model 1”,并將其分配給 myCar
變量。
構(gòu)造函數(shù)模式
構(gòu)造函數(shù)模式使用 new
關(guān)鍵字從構(gòu)造函數(shù)創(chuàng)建對象。它允許您在構(gòu)造函數(shù)中定義和初始化對象屬性。
// Implementation example of the Constructor Pattern
function Person(name, age) {
this.name = name;
this.age = age;
}
const tope = new Person("Tope", 24);
上面的代碼定義了一個(gè)名為 Person 的構(gòu)造函數(shù),它接受兩個(gè)參數(shù):name 和 age。在函數(shù)內(nèi)部,name 和 age 值使用 this 關(guān)鍵字分配給新創(chuàng)建對象的相應(yīng)屬性。
稍后,通過使用參數(shù)“Tope”和 24 調(diào)用 Person 函數(shù),創(chuàng)建 Person 對象的新實(shí)例。這會(huì)創(chuàng)建一個(gè)新對象,其 name 屬性設(shè)置為“Tope”,age 屬性設(shè)置為 24,然后將其分配給變量 tope。此代碼的輸出是 Tope 保存一個(gè)對象,該對象表示一個(gè)名為“Tope”,年齡為 24 的人。
原型模式
JavaScript 中的原型模式專注于通過克隆或擴(kuò)展現(xiàn)有對象作為原型來創(chuàng)建對象。它允許我們在不顯式定義類的情況下創(chuàng)建新實(shí)例。在此模式中,對象充當(dāng)創(chuàng)建新對象的原型,從而實(shí)現(xiàn)繼承以及在多個(gè)對象之間共享屬性和方法。
// Prototype object
const carPrototype = {
wheels: 4,
startEngine() {
console.log("Engine started.");
},
stopEngine() {
console.log("Engine stopped.");
}
};
// Create new car instance using the prototype
const car1 = Object.create(carPrototype);
car1.make = "Toyota";
car1.model = "Camry";
// Create another car instance using the same prototype
const car2 = Object.create(carPrototype);
car2.make = "Honda";
car2.model = "Accord";
car1.startEngine(); // Output: "Engine started."
car2.stopEngine(); // Output: "Engine stopped."
在此示例中,汽車實(shí)例 car1 和 car2 是使用原型對象 carPrototype 創(chuàng)建的。car1 的品牌為“Toyota”,型號為“Camry”,而 car2 的品牌為“Honda”,型號為“Accord”。調(diào)用 car1.startEngine()
時(shí),它會(huì)輸出“發(fā)動(dòng)機(jī)已啟動(dòng)?!?,調(diào)用 car2.stopEngine()
時(shí),它會(huì)輸出“發(fā)動(dòng)機(jī)已停止?!薄_@演示了利用原型對象在多個(gè)實(shí)例之間共享屬性和方法。
建造者模式
在建造者模式中,一個(gè)建造者類或?qū)ο筘?fù)責(zé)構(gòu)建最終對象。它提供了一組方法來配置和設(shè)置正在構(gòu)建的對象的屬性。構(gòu)建過程通常涉及按特定順序調(diào)用這些方法以逐步構(gòu)建對象。
class CarBuilder {
constructor() {
this.car = new Car();
}
setMake(make) {
this.car.make = make;
return this;
}
setModel(model) {
this.car.model = model;
return this;
}
setEngine(engine) {
this.car.engine = engine;
return this;
}
setWheels(wheels) {
this.car.wheels = wheels;
return this;
}
build() {
return this.car;
}
}
class Car {
constructor() {
this.make = "";
this.model = "";
this.engine = "";
this.wheels = 0;
}
displayInfo() {
console.log(Make: ${this.make}, Model: ${this.model}, Engine: ${this.engine}, Wheels: ${this.wheels});
}
}
// Usage
const carBuilder = new CarBuilder();
const car = carBuilder.setMake("Toyota").setModel("Camry").setEngine("V6").setWheels(4).build();
car.displayInfo(); // Output: Make: Toyota, Model: Camry, Engine: V6, Wheels: 4
在此示例中, CarBuilder
類允許構(gòu)建具有不同屬性的 Car 對象。通過調(diào)用 setMake
、 setModel
、 setEngine
、 setWheels
方法,可以設(shè)置 Car 對象的屬性。build 方法完成構(gòu)建并返回完全構(gòu)建的 Car 對象。Car 類表示汽車,并包含一個(gè) displayInfo
方法來記錄其詳細(xì)信息。通過創(chuàng)建一個(gè) carBuilder
實(shí)例并鏈接屬性設(shè)置方法,可以構(gòu)建具有特定品牌、型號、發(fā)動(dòng)機(jī)和車輪值的汽車對象。調(diào)用 car.displayInfo()
會(huì)顯示汽車的信息。
模塊模式
模塊模式將相關(guān)的方法和屬性封裝到單個(gè)模塊中,提供了一種組織和保護(hù)代碼的簡潔方式。它允許私有和公有成員,實(shí)現(xiàn)信息隱藏并防止全局命名空間污染。
const MyModule = (function() {
// Private members
let privateVariable = "I am private";
function privateMethod() {
console.log("This is a private method");
}
// Public members
return {
publicVariable: "I am public",
publicMethod() {
console.log("This is a public method");
// Accessing private members within the module
console.log(privateVariable);
privateMethod();
}
};
})();
// Usage
console.log(MyModule.publicVariable); // Output: "I am public"
MyModule.publicMethod(); // Output: "This is a public method" "I am private" "This is a private method"
在此示例中,代碼使用立即調(diào)用的函數(shù)表達(dá)式 (IIFE) 來封裝私有和公有成員。該模塊具有私有變量和方法,以及公有變量和方法。訪問時(shí),公有成員提供預(yù)期的輸出。此模式允許受控訪問封裝的私有成員,同時(shí)公開選定的公有成員。
- 結(jié)構(gòu)型模式
結(jié)構(gòu)型模式專注于組織和組合對象以形成更大的結(jié)構(gòu)。它們有助于組合對象,定義它們之間的關(guān)系并提供靈活的方式來操縱它們的結(jié)構(gòu)。JavaScript 中一些常用的結(jié)構(gòu)型模式包括:
-
裝飾器模式
-
外觀模式
-
適配器
-
橋接
-
組合
裝飾器模式
裝飾器模式允許您動(dòng)態(tài)地添加行為或修改對象的現(xiàn)有行為。它通過用一個(gè)或多個(gè)裝飾器包裝對象來增強(qiáng)其功能,而無需修改其結(jié)構(gòu)。
// Implementation example of the Decorator Pattern
class Coffee {
getCost() {
return 1;
}
}
class CoffeeDecorator {
constructor(coffee) {
this.coffee = coffee;
}
getCost() {
return this.coffee.getCost() + 0.5;
}
}
const myCoffee = new Coffee();
const coffeeWithMilk = new CoffeeDecorator(myCoffee);
console.log(coffeeWithMilk.getCost()); // Output: 1.5
在此示例中, CoffeeDecorator
類包裝了一個(gè)基礎(chǔ) Coffee
對象并添加了其他功能。它有一個(gè) getCost
方法,該方法通過將基礎(chǔ)咖啡的成本與 0.5 的額外成本相結(jié)合來計(jì)算總成本。
在使用部分,創(chuàng)建了 myCoffee
類的 Coffee
實(shí)例。然后,實(shí)例化 coffeeWithMilk
類的 CoffeeDecorator
實(shí)例,傳遞 myCoffee
作為參數(shù)。調(diào)用 coffeeWithMilk.getCost()
時(shí),它返回添加了裝飾器成本后的咖啡總成本,結(jié)果輸出為 1.5。此示例說明了裝飾器模式如何通過動(dòng)態(tài)添加或修改對象的屬性或方法來擴(kuò)展對象的功能。
外觀模式
外觀模式為復(fù)雜子系統(tǒng)提供了一個(gè)簡化的接口,充當(dāng)一個(gè)隱藏底層實(shí)現(xiàn)細(xì)節(jié)的面向前端的接口。它通過提供一個(gè)高級別接口,提供了一種與復(fù)雜系統(tǒng)交互的便捷方式。
// Implementation example of the Facade Pattern
class SubsystemA {
operationA() {
console.log("Subsystem A operation.");
}
}
class SubsystemB {
operationB() {
console.log("Subsystem B operation.");
}
}
class Facade {
constructor() {
this.subsystemA = new SubsystemA();
this.subsystemB = new SubsystemB();
}
operation() {
this.subsystemA.operationA();
this.subsystemB.operationB();
}
}
const facade = new Facade();
facade.operation(); // Output: "Subsystem A operation." "Subsystem B operation."
在此示例中,代碼由三個(gè)類組成: SubsystemA
、 SubsystemB
和 Facade
。 SubsystemA
和 SubsystemB
類表示獨(dú)立的子系統(tǒng),并具有各自的 operationA
和 operationB
方法。 Facade
類用作簡化接口,它聚合了子系統(tǒng)功能。
在使用部分,創(chuàng)建了 facade
類的 Facade
實(shí)例。調(diào)用 facade.operation()
會(huì)觸發(fā)從 SubsystemA
執(zhí)行 operationA
,從 SubsystemB
執(zhí)行 operationB
。因此,輸出顯示“子系統(tǒng) A 操作?!?,后跟“子系統(tǒng) B 操作?!薄_@演示了外觀模式如何提供統(tǒng)一且簡化的接口來與復(fù)雜子系統(tǒng)進(jìn)行交互,抽象其復(fù)雜性并使其更易于使用。
適配器模式
適配器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許具有不兼容接口的對象通過充當(dāng)它們之間的橋梁而協(xié)同工作。它提供了一種將一個(gè)對象接口轉(zhuǎn)換為客戶端期望的另一個(gè)接口的方法。
// Implementation
class LegacyPrinter {
printLegacy(text) {
console.log(Legacy Printing: ${text});
}
}
// Target interface
class Printer {
print(text) {}
}
// Adapter
class PrinterAdapter extends Printer {
constructor() {
super();
this.legacyPrinter = new LegacyPrinter();
}
print(text) {
this.legacyPrinter.printLegacy(text);
}
}
// Usage
const printer = new PrinterAdapter();
printer.print("Hello, World!"); // Output: "Legacy Printing: Hello, World!"
在此代碼中,適配器模式用于彌合 LegacyPrinter
類與所需 Printer
接口之間的差距。 PrinterAdapter
擴(kuò)展 Printer
類,并在內(nèi)部利用 LegacyPrinter
來適配 print
方法。當(dāng)調(diào)用 printer.print("Hello, World!")
時(shí),它會(huì)有效地觸發(fā)舊版打印功能,輸出“舊版打印:你好,世界!”。這展示了適配器模式如何通過提供標(biāo)準(zhǔn)化接口來實(shí)現(xiàn)不兼容組件的集成。
橋接模式
橋接模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它將系統(tǒng)的抽象和實(shí)現(xiàn)分離,允許它們獨(dú)立演化。它通過使用接口或抽象類在兩者之間引入橋接。以下是一個(gè)代碼片段示例來說明橋接模式:
// Example
class Shape {
constructor(color) {
this.color = color;
}
draw() {}
}
// Concrete Abstractions
class Circle extends Shape {
draw() {
console.log(Drawing a ${this.color} circle);
}
}
class Square extends Shape {
draw() {
console.log(Drawing a ${this.color} square);
}
}
// Implementor
class Color {
getColor() {}
}
// Concrete Implementors
class RedColor extends Color {
getColor() {
return "red";
}
}
class BlueColor extends Color {
getColor() {
return "blue";
}
}
// Usage
const redCircle = new Circle(new RedColor());
redCircle.draw(); // Output: "Drawing a red circle"
const blueSquare = new Square(new BlueColor());
blueSquare.draw(); // Output: "Drawing a blue square"
在此示例中,我們有由 Shape 類表示的抽象,它具有顏色屬性和 draw 方法。具體抽象 Circle 和 Square 從 Shape 類繼承并實(shí)現(xiàn)其特定的繪制行為。由 Color 類表示,它聲明 getColor
方法。具體 Implementors
、 RedColor
和 BlueColor
從 Color 類繼承并提供各自的顏色實(shí)現(xiàn)。
在使用部分,我們創(chuàng)建具體抽象的實(shí)例,傳遞適當(dāng)?shù)木唧w實(shí)現(xiàn)者對象。這允許抽象將與顏色相關(guān)的功能委托給實(shí)現(xiàn)者。當(dāng)我們調(diào)用 draw 方法時(shí),它從實(shí)現(xiàn)者訪問顏色并相應(yīng)地執(zhí)行繪圖操作。
組合模式
組合模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,它允許您以統(tǒng)一的方式處理單個(gè)對象和對象組合。它使您可以創(chuàng)建層次結(jié)構(gòu),其中每個(gè)元素都可以被視為單個(gè)對象或?qū)ο蠹稀T撃J绞褂靡粋€(gè)公共接口來表示單個(gè)對象(葉節(jié)點(diǎn))和組合(復(fù)合節(jié)點(diǎn)),允許客戶端以統(tǒng)一的方式與它們交互。
// Implementation
class Employee {
constructor(name) {
this.name = name;
}
print() {
console.log(Employee: ${this.name});
}
}
// Composite
class Manager extends Employee {
constructor(name) {
super(name);
this.employees = [];
}
add(employee) {
this.employees.push(employee);
}
remove(employee) {
const index = this.employees.indexOf(employee);
if (index !== -1) {
this.employees.splice(index, 1);
}
}
print() {
console.log(Manager: ${this.name});
for (const employee of this.employees) {
employee.print();
}
}
}
// Usage
const john = new Employee("John Doe");
const jane = new Employee("Jane Smith");
const mary = new Manager("Mary Johnson");
mary.add(john);
mary.add(jane);
const peter = new Employee("Peter Brown");
const bob = new Manager("Bob Williams");
bob.add(peter);
bob.add(mary);
bob.print();
在此示例中,我們有 Component 類 Employee,它表示單個(gè)員工。Composite 類 Manager 擴(kuò)展了 Employee 類,可以包含一組員工。它提供了將員工添加到集合中和從集合中刪除員工的方法,并重寫 print 方法以顯示經(jīng)理的姓名和他們下面的員工。
在使用部分,我們創(chuàng)建了一個(gè)復(fù)合層次結(jié)構(gòu),其中 Manager 對象既可以包含單個(gè)員工(Employee),也可以包含其他經(jīng)理(Manager)。我們將員工添加到經(jīng)理中,構(gòu)建一個(gè)層次結(jié)構(gòu)。最后,我們在頂級經(jīng)理上調(diào)用 print 方法,該方法遞歸打印層次結(jié)構(gòu),顯示經(jīng)理及其各自的員工。
- 行為型模式
行為型模式關(guān)注對象之間的交互以及職責(zé)的分配。它們?yōu)閷ο笾g的通信、協(xié)調(diào)和協(xié)作提供了解決方案。以下是行為型模式的類型。
-
觀察者模式
-
策略模式
-
命令模式
-
迭代器模式
-
中介者模式
觀察者模式
觀察者模式在對象之間建立了一種一對多的關(guān)系,其中多個(gè)觀察者會(huì)收到有關(guān)主題狀態(tài)更改的通知。它支持對象之間的松散耦合,并促進(jìn)事件驅(qū)動(dòng)的通信。
// Implementation example of the Observer Pattern
class Subject {
constructor() {
this.observers = [];
}
addObserver(observer) {
this.observers.push(observer);
}
removeObserver(observer) {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
notifyObservers() {
this.observers.forEach((observer) => observer.update());
}
}
class Observer {
update() {
console.log("Observer is notified of changes.");
}
}
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.notifyObservers(); // Output: "Observer is notified of changes." "Observer is notified of changes."
在此示例中, Subject
類表示維護(hù)觀察者列表并提供添加、刪除和通知觀察者方法的主題。 Observer
類通過其 update
方法定義觀察者的行為。在使用部分,創(chuàng)建了 Subject
類的 subject
實(shí)例。還創(chuàng)建了兩個(gè) observer
實(shí)例,并使用 addObserver
方法將它們添加到主題中。
當(dāng)調(diào)用 subject.notifyObservers()
時(shí),它會(huì)為每個(gè)觀察者觸發(fā) update
方法。因此,輸出“觀察者已收到更改通知?!北挥涗浟藘纱危砻饔^察者已收到有關(guān)主題更改的通知。
策略模式
策略模式允許您將可互換算法封裝在單獨(dú)的策略對象中。它支持在運(yùn)行時(shí)動(dòng)態(tài)選擇算法,從而提高了靈活性和可擴(kuò)展性。
// Implementation example of the Strategy Pattern
class Context {
constructor(strategy) {
this.strategy = strategy;
}
executeStrategy() {
this.strategy.execute();
}
}
class ConcreteStrategyA {
execute() {
console.log("Strategy A is executed.");
}
}
class ConcreteStrategyB {
execute() {
console.log("Strategy B is executed.");
}
}
const contextA = new Context(new ConcreteStrategyA());
contextA.executeStrategy(); // Output: "Strategy A is executed."
const contextB = new Context(new ConcreteStrategyB());
contextB.executeStrategy(); // Output: "Strategy B is executed."
在此示例中, Context
類表示封裝不同策略的上下文,具有 strategy
屬性和 executeStrategy
方法。有兩個(gè)具體的策略類, ConcreteStrategyA
和 ConcreteStrategyB
,每個(gè)類都有自己的 execute
方法,該方法輸出特定消息。
在用法部分,使用 ConcreteStrategyA
作為策略創(chuàng)建 Context
類的 contextA
實(shí)例。調(diào)用 contextA.executeStrategy()
會(huì)調(diào)用 ConcreteStrategyA
的 execute
方法,從而輸出“執(zhí)行策略 A”。同樣,使用 ConcreteStrategyB
作為策略創(chuàng)建 contextB
實(shí)例,調(diào)用 contextB.executeStrategy()
會(huì)觸發(fā) ConcreteStrategyB
的 execute
方法,從而輸出“執(zhí)行策略 B”。這演示了策略模式如何通過將行為封裝在不同的策略對象中,允許在運(yùn)行時(shí)動(dòng)態(tài)選擇行為。
命令模式
命令模式將請求封裝成對象,允許你使用不同的請求對客戶端進(jìn)行參數(shù)化,對請求進(jìn)行排隊(duì)或記錄,并支持撤銷操作。它將請求的發(fā)送者和接收者解耦,從而提高松散耦合和靈活性。
// Implementation
class Receiver {
execute() {
console.log("Receiver executes the command.");
}
}
class Command {
constructor(receiver) {
this.receiver = receiver;
}
execute() {
this.receiver.execute();
}
}
class Invoker {
setCommand(command) {
this.command = command;
}
executeCommand() {
this.command.execute();
}
}
const receiver = new Receiver();
const command = new Command(receiver);
const invoker = new Invoker();
invoker.setCommand(command);
invoker.executeCommand(); // Output: "Receiver executes the command."
在這個(gè)示例中, Receiver
類在調(diào)用時(shí)執(zhí)行命令, Command
類封裝一個(gè)命令并將執(zhí)行委托給接收者。 Invoker
類設(shè)置并執(zhí)行命令。在使用部分,創(chuàng)建了接收者、命令和調(diào)用者。為調(diào)用者設(shè)置命令,調(diào)用 invoker.executeCommand()
執(zhí)行命令,結(jié)果輸出“接收者執(zhí)行命令”。
迭代器模式
迭代器模式是一種行為設(shè)計(jì)模式,它提供了一種按順序訪問聚合對象元素的方法,而無需公開其底層表示形式。它允許您以統(tǒng)一的方式遍歷對象集合,而無需考慮集合的具體實(shí)現(xiàn)。該模式將遍歷邏輯與集合分離,從而促進(jìn)了一種干凈且靈活的元素迭代方法。
// Implementation
class Collection {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
}
createIterator() {}
}
// Concrete Aggregate
class ConcreteCollection extends Collection {
createIterator() {
return new ConcreteIterator(this);
}
}
// Iterator
class Iterator {
constructor(collection) {
this.collection = collection;
this.index = 0;
}
hasNext() {}
next() {}
}
// Concrete Iterator
class ConcreteIterator extends Iterator {
hasNext() {
return this.index < this.collection.items.length;
}
next() {
return this.collection.items[this.index++];
}
}
// Usage
const collection = new ConcreteCollection();
collection.addItem("Item 1");
collection.addItem("Item 2");
collection.addItem("Item 3");
const iterator = collection.createIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}
在此代碼中,我們有由 Collection 類表示的聚合,它定義了用于創(chuàng)建迭代器對象的接口。具體聚合 ConcreteCollection
擴(kuò)展了 Collection 類,并提供了迭代器創(chuàng)建的具體實(shí)現(xiàn)。
迭代器由 Iterator 類表示,該類定義了用于訪問和遍歷元素的接口。具體迭代器 ConcreteIterator
擴(kuò)展了 Iterator 類,并提供了迭代邏輯的具體實(shí)現(xiàn)。在使用部分,我們創(chuàng)建了具體聚合 ConcreteCollection
的實(shí)例,并向其中添加了項(xiàng)目。然后,我們使用 createIterator
方法創(chuàng)建迭代器。通過使用迭代器的 hasNext
和 next 方法,我們遍歷集合并打印每個(gè)項(xiàng)目。
中介者模式
中介者模式通過引入一個(gè)中介者對象來簡化對象通信,該對象用作協(xié)調(diào)對象之間交互的中心樞紐。它封裝了通信邏輯,并為對象提供了注冊、發(fā)送和接收消息的方法。
// Implementation
class Mediator {
constructor() {
this.colleague1 = null;
this.colleague2 = null;
}
setColleague1(colleague) {
this.colleague1 = colleague;
}
setColleague2(colleague) {
this.colleague2 = colleague;
}
notifyColleague1(message) {
this.colleague1.receive(message);
}
notifyColleague2(message) {
this.colleague2.receive(message);
}
}
class Colleague {
constructor(mediator) {
this.mediator = mediator;
}
send(message) {
// Send a message to the mediator
this.mediator.notifyColleague2(message);
}
receive(message) {
console.log(Received message: ${message});
}
}
// Usage
const mediator = new Mediator();
const colleague1 = new Colleague(mediator);
const colleague2 = new Colleague(mediator);
mediator.setColleague1(colleague1);
mediator.setColleague2(colleague2);
colleague1.send("Hello Colleague 2!"); // Output: "Received message: Hello Colleague 2!"
在這個(gè)例子中,我們有一個(gè)中介者類,它充當(dāng)兩個(gè)同事對象之間的中介。中介者持有對同事的引用,并提供在它們之間發(fā)送消息的方法。
每個(gè) Colleague 對象都引用中介者,并可以通過通知中介者來發(fā)送消息。中介者繼而將消息中繼給適當(dāng)?shù)耐隆T诒纠?,Colleague 1 向 Colleague 2 發(fā)送消息,后者接收并記錄該消息。文章來源:http://www.zghlxwxcb.cn/news/detail-786162.html
結(jié)論
我們已經(jīng)探索了 JavaScript 中的一系列基本設(shè)計(jì)模式,包括創(chuàng)建型、結(jié)構(gòu)型和行為型模式。創(chuàng)建型模式允許我們以靈活高效的方式創(chuàng)建對象。結(jié)構(gòu)型模式有助于提高組織的靈活性與可擴(kuò)展性。行為型模式支持 JavaScript 對象之間的有效通信和交互。通過利用這些設(shè)計(jì)模式,JavaScript 開發(fā)人員可以提高代碼的可重用性、可維護(hù)性和整體系統(tǒng)性能。掌握了這些知識,我們就可以構(gòu)建滿足現(xiàn)代軟件開發(fā)需求的強(qiáng)大且高效的 JavaScript 應(yīng)用程序。文章來源地址http://www.zghlxwxcb.cn/news/detail-786162.html
到了這里,關(guān)于寫點(diǎn)東西《JavaScript 中的設(shè)計(jì)模式:綜合指南》的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!