设计模式的三大分类:创建型、结构型、行为型
设计模式是软件开发中解决常见问题的可复用方案,JavaScript作为一门灵活的语言,设计模式的应用尤为广泛。三大分类包括创建型、结构型和行为型,每种类型针对不同场景提供解决方案。
创建型模式
创建型模式关注对象的创建机制,通过控制对象的创建过程来提升代码的灵活性和可复用性。在JavaScript中,常见的创建型模式包括工厂模式、抽象工厂模式、单例模式、建造者模式和原型模式。
工厂模式
工厂模式通过一个公共接口创建对象,隐藏具体实现细节。例如,一个UI组件工厂根据输入类型返回不同组件:
class Button {
render() {
return '<button>Click me</button>';
}
}
class Input {
render() {
return '<input type="text" />';
}
}
function createComponent(type) {
switch (type) {
case 'button':
return new Button();
case 'input':
return new Input();
default:
throw new Error('Unknown component type');
}
}
const button = createComponent('button');
console.log(button.render()); // <button>Click me</button>
单例模式
单例模式确保一个类只有一个实例,并提供全局访问点。这在管理全局状态时特别有用:
class Logger {
constructor() {
if (Logger.instance) {
return Logger.instance;
}
this.logs = [];
Logger.instance = this;
}
log(message) {
this.logs.push(message);
console.log(`LOG: ${message}`);
}
printLogCount() {
console.log(`${this.logs.length} Logs`);
}
}
const logger1 = new Logger();
const logger2 = new Logger();
logger1.log('First message');
logger2.log('Second message');
logger1.printLogCount(); // 2 Logs
console.log(logger1 === logger2); // true
原型模式
JavaScript本身基于原型继承,原型模式通过克隆现有对象来创建新对象:
const carPrototype = {
wheels: 4,
start() {
console.log('Car started');
},
stop() {
console.log('Car stopped');
}
};
const myCar = Object.create(carPrototype);
myCar.color = 'red';
console.log(myCar.wheels); // 4
myCar.start(); // Car started
结构型模式
结构型模式关注如何组合类和对象形成更大的结构,主要包括适配器模式、桥接模式、组合模式、装饰器模式、外观模式、享元模式和代理模式。
适配器模式
适配器模式使接口不兼容的对象能够协同工作。例如将旧API适配到新系统:
class OldCalculator {
operations(a, b, operation) {
switch (operation) {
case 'add':
return a + b;
case 'sub':
return a - b;
default:
return NaN;
}
}
}
class NewCalculator {
add(a, b) {
return a + b;
}
subtract(a, b) {
return a - b;
}
}
class CalculatorAdapter {
constructor() {
this.calculator = new NewCalculator();
}
operations(a, b, operation) {
switch (operation) {
case 'add':
return this.calculator.add(a, b);
case 'sub':
return this.calculator.subtract(a, b);
default:
return NaN;
}
}
}
const oldCalc = new OldCalculator();
console.log(oldCalc.operations(5, 3, 'add')); // 8
const adapter = new CalculatorAdapter();
console.log(adapter.operations(5, 3, 'add')); // 8
装饰器模式
装饰器模式动态地给对象添加额外职责。在JavaScript中可以通过高阶函数实现:
function withLogging(fn) {
return function(...args) {
console.log(`Calling function with args: ${args}`);
const result = fn.apply(this, args);
console.log(`Function returned: ${result}`);
return result;
};
}
function add(a, b) {
return a + b;
}
const loggedAdd = withLogging(add);
loggedAdd(2, 3);
// Calling function with args: 2,3
// Function returned: 5
代理模式
代理模式为其他对象提供一种代理以控制对这个对象的访问。例如实现图片懒加载:
class ImageProxy {
constructor(src) {
this.src = src;
this.realImage = null;
}
display() {
if (!this.realImage) {
this.realImage = new RealImage(this.src);
this.realImage.loadFromServer();
}
this.realImage.display();
}
}
class RealImage {
constructor(src) {
this.src = src;
this.image = null;
}
loadFromServer() {
console.log(`Loading image from ${this.src}`);
this.image = document.createElement('img');
this.image.src = this.src;
}
display() {
console.log(`Displaying image ${this.src}`);
document.body.appendChild(this.image);
}
}
const proxy = new ImageProxy('example.jpg');
// 图片尚未加载
proxy.display(); // 加载并显示图片
行为型模式
行为型模式关注对象之间的通信和职责分配,主要包括责任链模式、命令模式、解释器模式、迭代器模式、中介者模式、备忘录模式、观察者模式、状态模式、策略模式、模板方法模式和访问者模式。
观察者模式
观察者模式定义对象间的一对多依赖,当一个对象状态改变时,所有依赖它的对象都会得到通知:
class Subject {
constructor() {
this.observers = [];
}
subscribe(observer) {
this.observers.push(observer);
}
unsubscribe(observer) {
this.observers = this.observers.filter(obs => obs !== observer);
}
notify(data) {
this.observers.forEach(observer => observer.update(data));
}
}
class Observer {
update(data) {
console.log(`Observer received data: ${data}`);
}
}
const subject = new Subject();
const observer1 = new Observer();
const observer2 = new Observer();
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.notify('Hello observers!');
// Observer received data: Hello observers!
// Observer received data: Hello observers!
策略模式
策略模式定义一系列算法,将它们封装起来并使它们可以相互替换:
class PaymentStrategy {
pay(amount) {
throw new Error('Method not implemented');
}
}
class CreditCardStrategy extends PaymentStrategy {
pay(amount) {
console.log(`Paying ${amount} using Credit Card`);
}
}
class PayPalStrategy extends PaymentStrategy {
pay(amount) {
console.log(`Paying ${amount} using PayPal`);
}
}
class ShoppingCart {
constructor() {
this.strategy = null;
this.amount = 0;
}
setStrategy(strategy) {
this.strategy = strategy;
}
checkout() {
if (!this.strategy) {
throw new Error('No payment strategy set');
}
this.strategy.pay(this.amount);
}
}
const cart = new ShoppingCart();
cart.amount = 100;
cart.setStrategy(new CreditCardStrategy());
cart.checkout(); // Paying 100 using Credit Card
cart.setStrategy(new PayPalStrategy());
cart.checkout(); // Paying 100 using PayPal
状态模式
状态模式允许对象在内部状态改变时改变它的行为:
class TrafficLight {
constructor() {
this.states = [new RedLight(), new YellowLight(), new GreenLight()];
this.current = this.states[0];
}
change() {
const currentIndex = this.states.indexOf(this.current);
this.current = this.states[(currentIndex + 1) % this.states.length];
}
sign() {
return this.current.sign();
}
}
class Light {
constructor(color) {
this.color = color;
}
sign() {
return this.color;
}
}
class RedLight extends Light {
constructor() {
super('red');
}
}
class YellowLight extends Light {
constructor() {
super('yellow');
}
}
class GreenLight extends Light {
constructor() {
super('green');
}
}
const trafficLight = new TrafficLight();
console.log(trafficLight.sign()); // red
trafficLight.change();
console.log(trafficLight.sign()); // yellow
trafficLight.change();
console.log(trafficLight.sign()); // green
trafficLight.change();
console.log(trafficLight.sign()); // red
迭代器模式
迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示:
class MyIterator {
constructor(collection) {
this.collection = collection;
this.index = 0;
}
next() {
return this.collection[this.index++];
}
hasNext() {
return this.index < this.collection.length;
}
}
class MyCollection {
constructor() {
this.items = [];
}
addItem(item) {
this.items.push(item);
}
getIterator() {
return new MyIterator(this.items);
}
}
const collection = new MyCollection();
collection.addItem('First');
collection.addItem('Second');
collection.addItem('Third');
const iterator = collection.getIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}
// First
// Second
// Third
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn