设计模式
设计模式是一套被反复验证的代码设计经验,用于解决常见的软件设计问题。根据用途,设计模式总共有 23 种,一般分为三大类:创建型模式、结构型模式、和行为型模式。
创建型模式(5种)
用于创建对象,注重对象的创建方式,从而减少对象创建过程的复杂性。
-
单例模式(Singleton Pattern)
- 目的:确保一个类只有一个实例,并提供一个全局访问点。
- 应用场景:日志记录器、配置文件管理器、数据库连接池。
-
工厂方法模式(Factory Method Pattern)
- 目的:定义一个创建对象的接口,但让子类决定实例化哪一个类。
- 应用场景:日志系统生成不同的日志类型、数据库访问层。
-
抽象工厂模式(Abstract Factory Pattern)
- 目的:提供一个创建一系列相关或相互依赖对象的接口。
- 应用场景:跨平台 GUI 工具库(Windows 按钮、Mac 按钮等)、主题切换。
-
建造者模式(Builder Pattern)
- 目的:将复杂对象的构建过程与其表示分离,以便相同的构建过程可以创建不同的表示。
- 应用场景:创建复杂的对象,如 HTML 文档或游戏角色、车辆配置。
-
原型模式(Prototype Pattern)
- 目的:通过复制现有实例来创建新的对象,而不是通过实例化类。
- 应用场景:克隆对象、对象缓存。
结构型模式(7种)
用于组合类或对象以形成更大的结构,关注对象或类之间的组织方式。
-
适配器模式(Adapter Pattern)
- 目的:将一个类的接口转换为客户希望的另一个接口。
- 应用场景:电源适配器、旧系统和新系统之间的桥梁、第三方库集成。
-
桥接模式(Bridge Pattern)
- 目的:将抽象部分与实现部分分离,使它们可以独立变化。
- 应用场景:图形形状(如圆、矩形)与绘图实现(如 SVG、Canvas)、设备驱动程序。
-
装饰器模式(Decorator Pattern)
- 目的:动态地给对象添加功能,而不是通过子类扩展。
- 应用场景:咖啡订单系统添加配料(牛奶、糖)、文件读写功能扩展。
-
组合模式(Composite Pattern)
- 目的:将对象组合成树形结构以表示“整体-部分”的层次结构。
- 应用场景:文件系统(文件夹和文件)、GUI 组件树。
-
外观模式(Facade Pattern)
- 目的:为子系统的一组接口提供一个统一的高层接口。
- 应用场景:简化复杂 API 调用、库和框架的简化接口。
-
享元模式(Flyweight Pattern)
- 目的:通过共享尽可能多的数据来有效地支持大量细粒度对象。
- 应用场景:字符串池、图形对象共享、数据缓存。
-
代理模式(Proxy Pattern)
- 目的:为另一个对象提供一个替代或占位符。
- 应用场景:远程代理、虚拟代理、安全代理。
行为型模式(11种)
用于描述对象之间的通信和职责分配。
-
责任链模式(Chain of Responsibility Pattern)
- 目的:将请求沿着处理者链传递,直到被处理。
- 应用场景:日志级别过滤器、权限认证流程、请求处理管道。
-
命令模式(Command Pattern)
- 目的:将请求封装为对象,从而可以灵活地对请求排队、记录日志或撤销操作。
- 应用场景:文本编辑器的撤销/重做功能、任务调度。
-
迭代器模式(Iterator Pattern)
- 目的:提供一种方法来顺序访问集合对象的元素,而无需暴露其内部表示。
- 应用场景:遍历数组或列表、数据库结果集遍历。
-
中介者模式(Mediator Pattern)
- 目的:用一个中介对象封装一组对象之间的交互。
- 应用场景:聊天室系统、表单组件交互。
-
备忘录模式(Memento Pattern)
- 目的:在不破坏封装的前提下,捕获对象的内部状态以便之后恢复。
- 应用场景:保存游戏状态、撤销操作。
-
观察者模式(Observer Pattern)
- 目的:定义对象间的一对多依赖关系,当一个对象改变状态时,通知所有依赖它的对象。
- 应用场景:事件监听器、发布-订阅系统。
-
状态模式(State Pattern)
- 目的:允许对象在其内部状态更改时改变其行为。
- 应用场景:播放器(播放、暂停、停止)、状态机。
-
策略模式(Strategy Pattern)
- 目的:定义一系列算法,并将每种算法封装起来,使它们可以互换。
- 应用场景:支付系统(信用卡、PayPal、比特币)、排序算法。
-
模板方法模式(Template Method Pattern)
- 目的:定义一个操作的算法骨架,并将一些步骤延迟到子类中。
- 应用场景:算法的通用流程实现、代码生成器。
-
访问者模式(Visitor Pattern)
- 目的:在不改变类的前提下,为类的元素增加新的行为。
- 应用场景:编译器解析 AST(抽象语法树)、对象结构的操作。
-
解释器模式(Interpreter Pattern)
- 目的:定义一种语言的文法,并提供一个解释器来处理这种文法的句子。
- 应用场景:SQL 解析器、数学表达式解析器、脚本语言解释器。
总结
类型 | 模式 |
---|---|
创建型模式 | 单例、工厂方法、抽象工厂、建造者、原型 |
结构型模式 | 适配器、桥接、装饰器、组合、外观、享元、代理 |
行为型模式 | 责任链、命令、迭代器、中介者、备忘录、观察者、状态、策略、模板方法、访问者、解释器 |
这些模式可以根据具体需求灵活运用,提高代码的可读性、复用性和可扩展性。
创建型模式
1. 单例模式
懒汉式
懒汉式单例模式在第一次调用 getInstance
方法时创建实例。
class LazySingleton {
private static instance: LazySingleton;
// 私有构造方法,防止被实例化
private constructor() {}
// 静态方法,创建实例
public static getInstance(): LazySingleton {
if (!LazySingleton.instance) {
LazySingleton.instance = new LazySingleton();
}
return LazySingleton.instance;
}
// 示例方法
public showMessage(): void {
console.log("Hello World!");
}
}
饿汉式
饿汉式单例模式在类加载时就创建实例。
class EagerSingleton {
private static instance: EagerSingleton = new EagerSingleton();
// 私有构造方法,防止被实例化
private constructor() {}
// 静态方法,获取实例
public static getInstance(): EagerSingleton {
return EagerSingleton.instance;
}
// 示例方法
public showMessage(): void {
console.log("Hello World!");
}
}
2. 工厂方法模式
功能说明
- 定义产品接口,所有具体产品都必须实现这个接口。
- 创建具体产品类,实现产品接口。
- 定义工厂接口,声明一个工厂方法,用于创建产品。
- 创建具体工厂类,实现工厂接口,创建并返回具体产品实例。
- 客户端代码通过传入不同的工厂对象,来获得不同类型的产品。
// 1. 定义产品接口
interface Product {
operation(): string;
}
// 2. 创建具体产品类 A
class ConcreteProductA implements Product {
operation(): string {
return "ConcreteProductA operation";
}
}
// 3. 创建具体产品类 B
class ConcreteProductB implements Product {
operation(): string {
return "ConcreteProductB operation";
}
}
// 4. 定义工厂接口
interface Creator {
createProduct(): Product;
}
// 5. 创建具体工厂类 A
class ConcreteCreatorA implements Creator {
createProduct(): Product {
return new ConcreteProductA();
}
}
// 6. 创建具体工厂类 B
class ConcreteCreatorB implements Creator {
createProduct(): Product {
return new ConcreteProductB();
}
}
// 7. 客户端代码
function clientCode(creator: Creator) {
const product = creator.createProduct();
console.log(product.operation());
}
// 8. 客户端执行
const creatorA = new ConcreteCreatorA();
clientCode(creatorA);
const creatorB = new ConcreteCreatorB();
clientCode(creatorB);
3. 抽象工厂模式
功能说明
- 定义抽象产品接口,声明产品的公共方法。
- 创建具体产品类,实现抽象产品接口。
- 定义抽象工厂接口,声明创建产品的方法。
- 创建具体工厂类,实现抽象工厂接口,创建并返回具体产品实例。
- 客户端代码通过传入不同的工厂对象,来获得不同类型的产品。
// 抽象产品接口
interface Button {
render(): string;
}
interface Input {
render(): string;
}
// 具体产品 - Material Design 风格
class MaterialButton implements Button {
render(): string {
return "Material Design 按钮";
}
}
class MaterialInput implements Input {
render(): string {
return "Material Design 输入框";
}
}
// 具体产品 - iOS 风格
class IOSButton implements Button {
render(): string {
return "iOS 按钮";
}
}
class IOSInput implements Input {
render(): string {
return "iOS 输入框";
}
}
// 抽象工厂接口
interface UIFactory {
createButton(): Button;
createInput(): Input;
}
// 具体工厂 - Material Design
class MaterialFactory implements UIFactory {
createButton(): Button {
return new MaterialButton();
}
createInput(): Input {
return new MaterialInput();
}
}
// 具体工厂 - iOS
class IOSFactory implements UIFactory {
createButton(): Button {
return new IOSButton();
}
createInput(): Input {
return new IOSInput();
}
}
// 使用示例
function createUI(factory: UIFactory) {
const button = factory.createButton();
const input = factory.createInput();
console.log(button.render());
console.log(input.render());
}
// 创建 Material Design UI
const materialFactory = new MaterialFactory();
createUI(materialFactory);
// 创建 iOS UI
const iosFactory = new IOSFactory();
createUI(iosFactory);
4. 建造者模式
功能说明
- 定义产品类,包含产品的各个部分及其设置方法。
- 定义构建器接口,声明构建产品各部分的方法和获取产品的方法。
- 创建具体构建器类,实现构建器接口,构建并返回具体产品实例。
- 创建指导者类,负责调用构建器的方法来构建产品。
- 客户端代码通过指导者类来构建不同的产品。
// 产品类
class Computer {
private cpu: string = "";
private memory: string = "";
private disk: string = "";
setCPU(cpu: string) {
this.cpu = cpu;
}
setMemory(memory: string) {
this.memory = memory;
}
setDisk(disk: string) {
this.disk = disk;
}
showSpecs() {
console.log(`电脑配置:
CPU: ${this.cpu}
内存: ${this.memory}
硬盘: ${this.disk}`);
}
}
// 构建器接口
interface ComputerBuilder {
buildCPU(): void;
buildMemory(): void;
buildDisk(): void;
getResult(): Computer;
}
// 高配电脑构建器
class HighEndComputerBuilder implements ComputerBuilder {
private computer: Computer = new Computer();
buildCPU() {
this.computer.setCPU("i9处理器");
}
buildMemory() {
this.computer.setMemory("32GB DDR5");
}
buildDisk() {
this.computer.setDisk("2TB NVMe SSD");
}
getResult() {
return this.computer;
}
}
// 低配电脑构建器
class BudgetComputerBuilder implements ComputerBuilder {
private computer: Computer = new Computer();
buildCPU() {
this.computer.setCPU("i3处理器");
}
buildMemory() {
this.computer.setMemory("8GB DDR4");
}
buildDisk() {
this.computer.setDisk("256GB SSD");
}
getResult() {
return this.computer;
}
}
// 指导者类
class Director {
construct(builder: ComputerBuilder): Computer {
builder.buildCPU();
builder.buildMemory();
builder.buildDisk();
return builder.getResult();
}
}
// 客户端使用
const director = new Director();
const highEndPC = director.construct(new HighEndComputerBuilder());
const budgetPC = director.construct(new BudgetComputerBuilder());
highEndPC.showSpecs();
budgetPC.showSpecs();
5. 原型模式
功能说明
- 定义原型接口:声明一个
clone
方法,用于复制对象。 - 创建具体类:实现原型接口,提供
clone
方法的具体实现。 - 创建原型管理器:负责存储和复制原型实例。
- 客户端代码:通过原型管理器来获取克隆的对象。
// 原型接口
interface Prototype {
clone(): Prototype;
}
// 具体图形类
class Shape implements Prototype {
private color: string;
private type: string;
constructor(color: string, type: string) {
this.color = color;
this.type = type;
}
clone(): Shape {
return new Shape(this.color, this.type);
}
getInfo(): string {
return `${this.color} ${this.type}`;
}
}
// 原型管理器
class ShapeCache {
private static shapes: Map<string, Shape> = new Map();
public static getShape(id: string): Shape {
const cachedShape = ShapeCache.shapes.get(id);
return cachedShape ? cachedShape.clone() : null;
}
public static loadCache(): void {
const circle = new Shape("红色", "圆形");
const square = new Shape("蓝色", "方形");
const triangle = new Shape("绿色", "三角形");
ShapeCache.shapes.set("1", circle);
ShapeCache.shapes.set("2", square);
ShapeCache.shapes.set("3", triangle);
}
}
// 使用示例
ShapeCache.loadCache();
const shape1 = ShapeCache.getShape("1");
console.log(`复制的形状: ${shape1.getInfo()}`);
const shape2 = ShapeCache.getShape("2");
console.log(`复制的形状: ${shape2.getInfo()}`);
const shape3 = ShapeCache.getShape("3");
console.log(`复制的形状: ${shape3.getInfo()}`);
结构型模式
1. 适配器模式
功能说明
- 定义目标接口,声明客户端需要的方法。
- 创建现有类,包含需要适配的方法。
- 创建适配器类,实现目标接口,并在适配器类中调用现有类的方法。
- 客户端代码通过适配器类来调用现有类的方法。
// 1. 定义目标接口
interface Target {
request(): string;
}
// 2. 创建现有类
class Adaptee {
specificRequest(): string {
return "特殊请求";
}
}
// 3. 创建适配器类
class Adapter implements Target {
private adaptee: Adaptee;
constructor(adaptee: Adaptee) {
this.adaptee = adaptee;
}
request(): string {
return this.adaptee.specificRequest();
}
}
// 4. 客户端代码
function clientCode(target: Target) {
console.log(target.request());
}
// 使用示例
const adaptee = new Adaptee();
const adapter = new Adapter(adaptee);
clientCode(adapter);
2. 桥接模式
功能说明
- 定义实现接口,声明实现部分的方法。
- 创建具体实现类,实现实现接口。
- 定义抽象类,包含实现接口的引用,并声明抽象部分的方法。
- 创建扩展抽象类,继承抽象类,实现抽象部分的方法。
- 客户端代码通过抽象类来调用实现部分的方法。
// 1. 定义实现接口
interface Implementor {
operationImpl(): string;
}
// 2. 创建具体实现类 A
class ConcreteImplementorA implements Implementor {
operationImpl(): string {
return "具体实现 A";
}
}
// 3. 创建具体实现类 B
class ConcreteImplementorB implements Implementor {
operationImpl(): string {
return "具体实现 B";
}
}
// 4. 定义抽象类
abstract class Abstraction {
protected implementor: Implementor;
constructor(implementor: Implementor) {
this.implementor = implementor;
}
abstract operation(): string;
}
// 5. 创建扩展抽象类
class RefinedAbstraction extends Abstraction {
operation(): string {
return this.implementor.operationImpl();
}
}
// 6. 客户端代码
function clientCode(abstraction: Abstraction) {
console.log(abstraction.operation());
}
// 使用示例
const implementorA = new ConcreteImplementorA();
const abstractionA = new RefinedAbstraction(implementorA);
clientCode(abstractionA);
const implementorB = new ConcreteImplementorB();
const abstractionB = new RefinedAbstraction(implementorB);
clientCode(abstractionB);
3. 装饰器模式
功能说明
- 定义组件接口,声明组件的方法。
- 创建具体组件类,实现组件接口。
- 创建装饰器类,实现组件接口,并包含一个组件的引用。
- 创建具体装饰器类,继承装饰器类,并在装饰器类中调用组件的方法。
- 客户端代码通过装饰器类来调用组件的方法。
// 1. 定义组件接口
interface Component {
operation(): string;
}
// 2. 创建具体组件类
class ConcreteComponent implements Component {
operation(): string {
return "具体组件";
}
}
// 3. 创建装饰器类
class Decorator implements Component {
protected component: Component;
constructor(component: Component) {
this.component = component;
}
operation(): string {
return this.component.operation();
}
}
// 4. 创建具体装饰器类 A
class ConcreteDecoratorA extends Decorator {
operation(): string {
return `装饰器 A(${super.operation()})`;
}
}
// 5. 创建具体装饰器类 B
class ConcreteDecoratorB extends Decorator {
operation(): string {
return `装饰器 B(${super.operation()})`;
}
}
// 6. 客户端代码
function clientCode(component: Component) {
console.log(component.operation());
}
// 使用示例
const simple = new ConcreteComponent();
console.log("简单组件:");
clientCode(simple);
const decoratorA = new ConcreteDecoratorA(simple);
console.log("装饰器 A:");
clientCode(decoratorA);
const decoratorB = new ConcreteDecoratorB(decoratorA);
console.log("装饰器 B:");
clientCode(decoratorB);
4. 组合模式
功能说明
- 定义组件接口,声明组件的方法。
- 创建叶子组件类,实现组件接口。
- 创建组合组件类,实现组件接口,并包含一个组件的集合。
- 客户端代码通过组合组件类来调用叶子组件的方法。
// 1. 定义组件接口
interface Component {
operation(): string;
}
// 2. 创建叶子组件类
class Leaf implements Component {
operation(): string {
return "叶子";
}
}
// 3. 创建组合组件类
class Composite implements Component {
private children: Component[] = [];
add(component: Component): void {
this.children.push(component);
}
operation(): string {
return `组合(${this.children
.map((child) => child.operation())
.join(", ")})`;
}
}
// 4. 客户端代码
function clientCode(component: Component) {
console.log(component.operation());
}
// 使用示例
const leaf = new Leaf();
console.log("叶子组件:");
clientCode(leaf);
const composite = new Composite();
composite.add(leaf);
composite.add(new Leaf());
console.log("组合组件:");
clientCode(composite);
5. 外观模式
功能说明
- 创建子系统类,包含子系统的具体方法。
- 创建外观类,包含子系统的引用,并提供简化的接口。
- 客户端代码通过外观类来调用子系统的方法。
// 1. 创建子系统类
class Subsystem1 {
operation1(): string {
return "子系统 1 操作";
}
}
class Subsystem2 {
operation2(): string {
return "子系统 2 操作";
}
}
// 2. 创建外观类
class Facade {
private subsystem1: Subsystem1;
private subsystem2: Subsystem2;
constructor(subsystem1: Subsystem1, subsystem2: Subsystem2) {
this.subsystem1 = subsystem1;
this.subsystem2 = subsystem2;
}
operation(): string {
return `${this.subsystem1.operation1()} 和 ${this.subsystem2.operation2()}`;
}
}
// 3. 客户端代码
function clientCode(facade: Facade) {
console.log(facade.operation());
}
// 使用示例
const subsystem1 = new Subsystem1();
const subsystem2 = new Subsystem2();
const facade = new Facade(subsystem1, subsystem2);
clientCode(facade);
6. 享元模式
功能说明
- 创建享元接口,声明享元的方法。
- 创建具体享元类,实现享元接口。
- 创建享元工厂类,负责创建和管理享元实例。
- 客户端代码通过享元工厂类来获取享元实例。
// 1. 创建享元接口
interface Flyweight {
operation(extrinsicState: string): void;
}
// 2. 创建具体享元类
class ConcreteFlyweight implements Flyweight {
private intrinsicState: string;
constructor(intrinsicState: string) {
this.intrinsicState = intrinsicState;
}
operation(extrinsicState: string): void {
console.log(
`享元: 内部状态 = ${this.intrinsicState}, 外部状态 = ${extrinsicState}`
);
}
}
// 3. 创建享元工厂类
class FlyweightFactory {
private flyweights: { [key: string]: Flyweight } = {};
getFlyweight(key: string): Flyweight {
if (!this.flyweights[key]) {
this.flyweights[key] = new ConcreteFlyweight(key);
}
return this.flyweights[key];
}
}
// 4. 客户端代码
function clientCode(
factory: FlyweightFactory,
key: string,
extrinsicState: string
) {
const flyweight = factory.getFlyweight(key);
flyweight.operation(extrinsicState);
}
// 使用示例
const factory = new FlyweightFactory();
clientCode(factory, "A", "外部状态 1");
clientCode(factory, "B", "外部状态 2");
clientCode(factory, "A", "外部状态 3");
7. 代理模式
功能说明
- 定义主题接口,声明主题的方法。
- 创建真实主题类,实现主题接口。
- 创建代理类,实现主题接口,并包含真实主题的引用。
- 客户端代码通过代理类来调用真实主题的方法。
// 1. 定义主题接口
interface Subject {
request(): void;
}
// 2. 创建真实主题类
class RealSubject implements Subject {
request(): void {
console.log("真实主题请求");
}
}
// 3. 创建代理类
class Proxy implements Subject {
private realSubject: RealSubject;
constructor(realSubject: RealSubject) {
this.realSubject = realSubject;
}
request(): void {
console.log("代理请求");
this.realSubject.request();
}
}
// 4. 客户端代码
function clientCode(subject: Subject) {
subject.request();
}
// 使用示例
const realSubject = new RealSubject();
const proxy = new Proxy(realSubject);
clientCode(proxy);
行为型模式
1. 责任链模式
功能说明
- 定义处理者接口,声明处理请求的方法。
- 创建具体处理者类,实现处理者接口,并包含下一个处理者的引用。
- 客户端代码通过具体处理者类来处理请求。
// 1. 定义处理者接口
interface Handler {
setNext(handler: Handler): Handler;
handle(request: string): string;
}
// 2. 创建抽象处理者类
abstract class AbstractHandler implements Handler {
private nextHandler: Handler;
setNext(handler: Handler): Handler {
this.nextHandler = handler;
return handler;
}
handle(request: string): string {
if (this.nextHandler) {
return this.nextHandler.handle(request);
}
return null;
}
}
// 3. 创建具体处理者类 A
class ConcreteHandlerA extends AbstractHandler {
handle(request: string): string {
if (request === "A") {
return `处理者 A 处理请求 ${request}`;
}
return super.handle(request);
}
}
// 4. 创建具体处理者类 B
class ConcreteHandlerB extends AbstractHandler {
handle(request: string): string {
if (request === "B") {
return `处理者 B 处理请求 ${request}`;
}
return super.handle(request);
}
}
// 5. 客户端代码
function clientCode(handler: Handler) {
const requests = ["A", "B", "C"];
for (const request of requests) {
const result = handler.handle(request);
if (result) {
console.log(result);
} else {
console.log(`请求 ${request} 没有处理`);
}
}
}
// 使用示例
const handlerA = new ConcreteHandlerA();
const handlerB = new ConcreteHandlerB();
handlerA.setNext(handlerB);
clientCode(handlerA);
2. 命令模式
功能说明
- 定义命令接口,声明执行命令的方法。
- 创建具体命令类,实现命令接口,并包含接收者的引用。
- 创建接收者类,包含具体操作的方法。
- 创建调用者类,包含命令的引用,并调用命令的方法。
- 客户端代码通过调用者类来执行命令。
// 1. 定义命令接口
interface Command {
execute(): void;
}
// 2. 创建接收者类
class Receiver {
action(): void {
console.log("接收者执行操作");
}
}
// 3. 创建具体命令类
class ConcreteCommand implements Command {
private receiver: Receiver;
constructor(receiver: Receiver) {
this.receiver = receiver;
}
execute(): void {
this.receiver.action();
}
}
// 4. 创建调用者类
class Invoker {
private command: Command;
setCommand(command: Command): void {
this.command = command;
}
executeCommand(): void {
this.command.execute();
}
}
// 5. 客户端代码
function clientCode(invoker: Invoker, command: Command) {
invoker.setCommand(command);
invoker.executeCommand();
}
// 使用示例
const receiver = new Receiver();
const command = new ConcreteCommand(receiver);
const invoker = new Invoker();
clientCode(invoker, command);
3. 迭代器模式
功能说明
- 定义迭代器接口,声明遍历集合的方法。
- 创建具体迭代器类,实现迭代器接口。
- 定义集合接口,声明创建迭代器的方法。
- 创建具体集合类,实现集合接口,并返回具体迭代器实例。
- 客户端代码通过具体集合类来获取迭代器,并遍历集合。
// 1. 定义迭代器接口
interface Iterator<T> {
current(): T;
next(): T;
hasNext(): boolean;
}
// 2. 创建具体迭代器类
class ConcreteIterator<T> implements Iterator<T> {
private collection: T[];
private position: number = 0;
constructor(collection: T[]) {
this.collection = collection;
}
current(): T {
return this.collection[this.position];
}
next(): T {
const item = this.collection[this.position];
this.position += 1;
return item;
}
hasNext(): boolean {
return this.position < this.collection.length;
}
}
// 3. 定义集合接口
interface Aggregate<T> {
createIterator(): Iterator<T>;
}
// 4. 创建具体集合类
class ConcreteAggregate<T> implements Aggregate<T> {
private collection: T[] = [];
addItem(item: T): void {
this.collection.push(item);
}
createIterator(): Iterator<T> {
return new ConcreteIterator(this.collection);
}
}
// 5. 客户端代码
function clientCode<T>(aggregate: Aggregate<T>) {
const iterator = aggregate.createIterator();
while (iterator.hasNext()) {
console.log(iterator.next());
}
}
// 使用示例
const aggregate = new ConcreteAggregate<string>();
aggregate.addItem("Item 1");
aggregate.addItem("Item 2");
aggregate.addItem("Item 3");
clientCode(aggregate);
4. 中介者模式
功能说明
- 定义中介者接口,声明中介者的方法。
- 创建具体中介者类,实现中介者接口,并包含同事类的引用。
- 定义同事类,包含中介者的引用,并通过中介者与其他同事类通信。
- 客户端代码通过具体中介者类来协调同事类之间的通信。
// 1. 定义中介者接口
interface Mediator {
notify(sender: object, event: string): void;
}
// 2. 创建具体中介者类
class ConcreteMediator implements Mediator {
private component1: Component1;
private component2: Component2;
constructor(c1: Component1, c2: Component2) {
this.component1 = c1;
this.component1.setMediator(this);
this.component2 = c2;
this.component2.setMediator(this);
}
notify(sender: object, event: string): void {
if (event === "A") {
console.log("中介者响应事件 A");
this.component2.doC();
}
if (event === "D") {
console.log("中介者响应事件 D");
this.component1.doB();
this.component2.doC();
}
}
}
// 3. 定义同事类
class BaseComponent {
protected mediator: Mediator;
setMediator(mediator: Mediator): void {
this.mediator = mediator;
}
}
class Component1 extends BaseComponent {
doA(): void {
console.log("组件 1 执行 A");
this.mediator.notify(this, "A");
}
doB(): void {
console.log("组件 1 执行 B");
this.mediator.notify(this, "B");
}
}
class Component2 extends BaseComponent {
doC(): void {
console.log("组件 2 执行 C");
this.mediator.notify(this, "C");
}
doD(): void {
console.log("组件 2 执行 D");
this.mediator.notify(this, "D");
}
}
// 4. 客户端代码
const c1 = new Component1();
const c2 = new Component2();
const mediator = new ConcreteMediator(c1, c2);
console.log("客户端触发事件 A");
c1.doA();
console.log("客户端触发事件 D");
c2.doD();
5. 备忘录模式
功能说明
- 定义备忘录类,包含需要保存的状态。
- 创建发起人类,包含状态,并创建和恢复备忘录的方法。
- 创建负责人类,管理备忘录的保存和恢复。
- 客户端代码通过负责人类来保存和恢复发起人的状态。
// 1. 定义备忘录类
class Memento {
private state: string;
constructor(state: string) {
this.state = state;
}
getState(): string {
return this.state;
}
}
// 2. 创建发起人类
class Originator {
private state: string;
setState(state: string): void {
this.state = state;
console.log(`发起人: 设置状态为 ${state}`);
}
saveStateToMemento(): Memento {
console.log(`发起人: 保存状态到备忘录`);
return new Memento(this.state);
}
getStateFromMemento(memento: Memento): void {
this.state = memento.getState();
console.log(`发起人: 从备忘录恢复状态为 ${this.state}`);
}
}
// 3. 创建负责人类
class Caretaker {
private mementoList: Memento[] = [];
add(memento: Memento): void {
this.mementoList.push(memento);
}
get(index: number): Memento {
return this.mementoList[index];
}
}
// 4. 客户端代码
const originator = new Originator();
const caretaker = new Caretaker();
originator.setState("状态 1");
originator.setState("状态 2");
caretaker.add(originator.saveStateToMemento());
originator.setState("状态 3");
caretaker.add(originator.saveStateToMemento());
originator.setState("状态 4");
console.log(`当前状态: ${originator.getStateFromMemento(caretaker.get(0))}`);
console.log(`当前状态: ${originator.getStateFromMemento(caretaker.get(1))}`);
6. 观察者模式
功能说明
- 定义观察者接口,声明更新方法。
- 创建具体观察者类,实现观察者接口。
- 定义主题接口,声明注册、注销和通知观察者的方法。
- 创建具体主题类,实现主题接口,并维护观察者列表。
- 客户端代码通过具体主题类来注册、注销和通知观察者。
// 1. 定义观察者接口
interface Observer {
update(message: string): void;
}
// 2. 创建具体观察者类
class ConcreteObserver implements Observer {
private name: string;
constructor(name: string) {
this.name = name;
}
update(message: string): void {
console.log(`${this.name} 收到消息: ${message}`);
}
}
// 3. 定义主题接口
interface Subject {
registerObserver(observer: Observer): void;
removeObserver(observer: Observer): void;
notifyObservers(): void;
}
// 4. 创建具体主题类
class ConcreteSubject implements Subject {
private observers: Observer[] = [];
private message: string;
registerObserver(observer: Observer): void {
this.observers.push(observer);
}
removeObserver(observer: Observer): void {
const index = this.observers.indexOf(observer);
if (index !== -1) {
this.observers.splice(index, 1);
}
}
notifyObservers(): void {
for (const observer of this.observers) {
observer.update(this.message);
}
}
setMessage(message: string): void {
this.message = message;
this.notifyObservers();
}
}
// 5. 客户端代码
const subject = new ConcreteSubject();
const observer1 = new ConcreteObserver("观察者 1");
const observer2 = new ConcreteObserver("观察者 2");
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.setMessage("消息 1");
subject.removeObserver(observer1);
subject.setMessage("消息 2");
7. 状态模式
功能说明
- 定义状态接口,声明状态的方法。
- 创建具体状态类,实现状态接口。
- 创建上下文类,包含状态的引用,并在上下文类中调用状态的方法。
- 客户端代码通过上下文类来改变状态。
// 1. 定义状态接口
interface State {
handle(context: Context): void;
}
// 2. 创建具体状态类 A
class ConcreteStateA implements State {
handle(context: Context): void {
console.log("状态 A 处理请求");
context.setState(new ConcreteStateB());
}
}
// 3. 创建具体状态类 B
class ConcreteStateB implements State {
handle(context: Context): void {
console.log("状态 B 处理请求");
context.setState(new ConcreteStateA());
}
}
// 4. 创建上下文类
class Context {
private state: State;
constructor(state: State) {
this.setState(state);
}
setState(state: State): void {
this.state = state;
console.log(`上下文: 状态已更改为 ${state.constructor.name}`);
}
request(): void {
this.state.handle(this);
}
}
// 5. 客户端代码
const context = new Context(new ConcreteStateA());
context.request();
context.request();
context.request();
8. 策略模式
功能说明
- 定义策略接口,声明策略的方法。
- 创建具体策略类,实现策略接口。
- 创建上下文类,包含策略的引用,并在上下文类中调用策略的方法。
- 客户端代码通过上下文类来设置和调用策略。
// 1. 定义策略接口
interface Strategy {
execute(a: number, b: number): number;
}
// 2. 创建具体策略类 A
class ConcreteStrategyA implements Strategy {
execute(a: number, b: number): number {
return a + b;
}
}
// 3. 创建具体策略类 B
class ConcreteStrategyB implements Strategy {
execute(a: number, b: number): number {
return a * b;
}
}
// 4. 创建上下文类
class Context {
private strategy: Strategy;
setStrategy(strategy: Strategy): void {
this.strategy = strategy;
}
executeStrategy(a: number, b: number): number {
return this.strategy.execute(a, b);
}
}
// 5. 客户端代码
const context = new Context();
context.setStrategy(new ConcreteStrategyA());
console.log("策略 A:", context.executeStrategy(3, 4));
context.setStrategy(new ConcreteStrategyB());
console.log("策略 B:", context.executeStrategy(3, 4));
9. 模板方法模式
功能说明
- 定义抽象类,包含模板方法和抽象方法。
- 创建具体类,继承抽象类,并实现抽象方法。
- 客户端代码通过具体类来调用模板方法。
// 1. 定义抽象类
abstract class AbstractClass {
templateMethod(): void {
this.baseOperation1();
this.requiredOperation1();
this.baseOperation2();
this.requiredOperation2();
this.hook();
}
baseOperation1(): void {
console.log("抽象类: 基本操作 1");
}
baseOperation2(): void {
console.log("抽象类: 基本操作 2");
}
abstract requiredOperation1(): void;
abstract requiredOperation2(): void;
hook(): void {}
}
// 2. 创建具体类 A
class ConcreteClassA extends AbstractClass {
requiredOperation1(): void {
console.log("具体类 A: 必须操作 1");
}
requiredOperation2(): void {
console.log("具体类 A: 必须操作 2");
}
}
// 3. 创建具体类 B
class ConcreteClassB extends AbstractClass {
requiredOperation1(): void {
console.log("具体类 B: 必须操作 1");
}
requiredOperation2(): void {
console.log("具体类 B: 必须操作 2");
}
hook(): void {
console.log("具体类 B: 可选操作");
}
}
// 4. 客户端代码
function clientCode(abstractClass: AbstractClass) {
abstractClass.templateMethod();
}
// 使用示例
console.log("具体类 A:");
clientCode(new ConcreteClassA());
console.log("具体类 B:");
clientCode(new ConcreteClassB());
10. 访问者模式
功能说明
- 定义访问者接口,声明访问方法。
- 创建具体访问者类,实现访问者接口。
- 定义元素接口,声明接受访问者的方法。
- 创建具体元素类,实现元素接口,并在接受访问者的方法中调用访问者的方法。
- 客户端代码通过具体元素类来接受访问者。
// 1. 定义访问者接口
interface Visitor {
visitConcreteElementA(element: ConcreteElementA): void;
visitConcreteElementB(element: ConcreteElementB): void;
}
// 2. 创建具体访问者类
class ConcreteVisitor1 implements Visitor {
visitConcreteElementA(element: ConcreteElementA): void {
console.log(`具体访问者 1 访问 ${element.operationA()}`);
}
visitConcreteElementB(element: ConcreteElementB): void {
console.log(`具体访问者 1 访问 ${element.operationB()}`);
}
}
class ConcreteVisitor2 implements Visitor {
visitConcreteElementA(element: ConcreteElementA): void {
console.log(`具体访问者 2 访问 ${element.operationA()}`);
}
visitConcreteElementB(element: ConcreteElementB): void {
console.log(`具体访问者 2 访问 ${element.operationB()}`);
}
}
// 3. 定义元素接口
interface Element {
accept(visitor: Visitor): void;
}
// 4. 创建具体元素类
class ConcreteElementA implements Element {
accept(visitor: Visitor): void {
visitor.visitConcreteElementA(this);
}
operationA(): string {
return "元素 A";
}
}
class ConcreteElementB implements Element {
accept(visitor: Visitor): void {
visitor.visitConcreteElementB(this);
}
operationB(): string {
return "元素 B";
}
}
// 5. 客户端代码
function clientCode(elements: Element[], visitor: Visitor) {
for (const element of elements) {
element.accept(visitor);
}
}
// 使用示例
const elements = [new ConcreteElementA(), new ConcreteElementB()];
console.log("具体访问者 1:");
const visitor1 = new ConcreteVisitor1();
clientCode(elements, visitor1);
console.log("具体访问者 2:");
const visitor2 = new ConcreteVisitor2();
clientCode(elements, visitor2);
11. 解释器模式
功能说明
- 定义表达式接口,声明解释方法。
- 创建终结符表达式类,实现表达式接口。
- 创建非终结符表达式类,实现表达式接口,并包含表达式的引用。
- 客户端代码通过非终结符表达式类来解释表达式。
// 1. 定义表达式接口
interface Expression {
interpret(context: string): boolean;
}
// 2. 创建终结符表达式类
class TerminalExpression implements Expression {
private data: string;
constructor(data: string) {
this.data = data;
}
interpret(context: string): boolean {
return context.includes(this.data);
}
}
// 3. 创建非终结符表达式类
class OrExpression implements Expression {
private expr1: Expression;
private expr2: Expression;
constructor(expr1: Expression, expr2: Expression) {
this.expr1 = expr1;
this.expr2 = expr2;
}
interpret(context: string): boolean {
return this.expr1.interpret(context) || this.expr2.interpret(context);
}
}
class AndExpression implements Expression {
private expr1: Expression;
private expr2: Expression;
constructor(expr1: Expression, expr2: Expression) {
this.expr1 = expr1;
this.expr2 = expr2;
}
interpret(context: string): boolean {
return this.expr1.interpret(context) && this.expr2.interpret(context);
}
}
// 4. 客户端代码
const expr1 = new TerminalExpression("A");
const expr2 = new TerminalExpression("B");
const orExpr = new OrExpression(expr1, expr2);
const andExpr = new AndExpression(expr1, expr2);
console.log(`A 或 B 包含在 "A C": ${orExpr.interpret("A C")}`);
console.log(`A 和 B 包含在 "A B": ${andExpr.interpret("A B")}`);