Web开发的设计模式
有时,当你不知如何着手时,为项目构建设计结构可能会令人望而生畏。了解设计模式可以帮助我们开发人员根据所需的可扩展性或功能类型,找到更好地构建软件的方法。
设计模式是软件设计中常见问题的典型解决方案。它们并非代码解决方案,而是一些通用概念,可以在软件中实现,以预期软件的特定行为。《设计模式:可复用面向对象软件的元素》一书已成为软件开发的经典著作,其中介绍了 23 种用于解决面向对象设计的模式。本文我将介绍前端开发中最常用的三种设计模式。
但首先,为什么学习设计模式如此重要?
1. 识别库和语言中的模式
一些库,例如 Angular,在其结构和创建问题解决方案的方式中运用了设计模式。这让我们了解如何利用这种现有行为来构建我们自己的解决方案。
2.避免重复造轮子
创建其他人以前遇到过并成功实施的解决方案比从头开始提出解决方案更容易。
3.共享词汇
在开发团队中,如果每个人都熟悉设计模式,那么讨论如何设计解决方案就会更容易。用名字来解释一个抽象的概念比解释整个概念更容易。
模式类型
根据其行为,设计模式可分为 3 种类型。
-
创建模式:提供一种结构来轻松创建对象,并在创建时提供一定的灵活性,并重用现有的代码。
-
结构模式:提供一种结构,帮助将对象和类组装成更大的结构。
-
行为模式:在对象之间分配责任并负责沟通。
单例模式
单例模式是一种创建型设计模式,它限制类只能拥有一个实例,同时创建指向该实例的全局访问点。它适用于需要控制对共享资源的访问的情况。
- 当你需要确保对某个资源的控制访问,而该资源如果同时被两个不同的对象更改,可能会导致不一致时,可以使用此模式。(例如,数据库、对象的状态)
class Singleton {
private static instance: Singleton;
private constructor() { }
public static getInstance(): Singleton {
if (!Singleton.instance) {
Singleton.instance = new Singleton();
}
return Singleton.instance;
}
}
观察者
观察者模式是一种行为设计模式,对象可以获取其观察对象上发生的任何事件的信息。观察者模式定义了一个订阅者方法,该方法会更新每个订阅自身的对象,确保每个订阅者都能获得最新的更新。
我们日常生活中观察者的一个例子就是订阅新闻通讯。加入邮件列表后,每当有新内容发布时,您都会收到通知。
- 当一个对象的更改可能需要更新其他对象,并且实际的对象集未知或动态变化时,请使用此模式。
class Observable {
// List of observers
private observers: Observer[] = [];
public attach(observer: Observer): void {
const exists = this.observers.includes(observer);
if (!exists) {
this.observers.push(observer);
}
}
public detach(observer: Observer): void {
const observerIndex = this.observers.indexOf(observer);
if (observerIndex !== -1) {
this.observers.splice(observerIndex, 1);
}
}
public notify(): void {
for (const observer of this.observers) {
observer.update(this);
}
}
}
class Observer {
public update(observable: Observable): void {
// Update observer according to Observable state
}
}
装饰器
装饰器是一种结构模式,它允许您通过添加包含行为的包装器来为对象添加新特性。
我们可以在食品配送应用程序中找到这种模式的例子,您可以为食物选择任何配料或额外内容,然后应用程序会将相应的费用添加到您的订单中。
- 当需要在运行时添加这些额外的行为,或者无法继承时,请使用此模式。
interface Coffee {
getCost(): int;
}
class SimpleCoffee implements Coffee {
public getCost(): int {
return 2;
}
}
class CoffeeDecorator implements Coffee {
protected decoratedCoffee: SimpleCoffee;
constructor(decoratedCoffee: SimpleCoffee) {
this.decoratedCoffee = decoratedComponent;
}
public getCost(): int {
return this.component.getCost();
}
}
class WithMilk extends CoffeeDecorator {
public getCost(): int {
return super.getCost + 0.5;
}
}
虽然了解这些设计模式有助于构建更好的解决方案,但并非每次遇到项目都需要用到它们。我们需要花些时间思考在自己的代码中实现它们的利弊。如果在特定情况下使用它们不会带来任何好处,请记住避免让代码过于复杂。
你在 Web 开发项目中使用过其他设计模式吗?请告诉我你最常用的是哪些。
要了解有关设计模式的更多信息,请查看:
Refractoring Guru - 设计模式