Typescript演绎设计模式之结构型模式(下)
2023-09-29 21:40:01
面向对象设计的结构型设计模式:外观、适配器、装饰器、代理和桥接模式
在软件开发中,设计模式是一种可重用的解决方案,用于解决常见问题。结构型设计模式侧重于类和对象的组合,以创建灵活且可维护的代码。在这篇文章中,我们将探讨五种重要的结构型设计模式:外观、适配器、装饰器、代理和桥接模式。
外观模式
想象一下你正在建造一所房子,你必须与水管工、电工和屋顶工等多个子系统进行交互。外观模式提供了一个统一的界面,可让你访问这些子系统,而无需了解它们的内部工作原理。
外观模式创建一个外观类,该类将子系统功能封装在一个简单的接口中。客户端代码只与外观类交互,从而简化了系统与子系统之间的通信。
优点:
- 减少客户端与子系统之间的依赖关系
- 简化客户端代码
- 提高灵活性,允许轻松更改或扩展子系统
代码示例:
class Facade {
private subsystem1: Subsystem1;
private subsystem2: Subsystem2;
constructor() {
this.subsystem1 = new Subsystem1();
this.subsystem2 = new Subsystem2();
}
public operation() {
this.subsystem1.operation1();
this.subsystem2.operation2();
}
}
// 使用外观模式
const facade = new Facade();
facade.operation();
适配器模式
假设你有一个旧系统,其接口与新系统不兼容。适配器模式允许你创建一个适配器类,该类将旧接口转换为新接口。
适配器模式将现有类包装在一个新的类中,该新类实现了所需的新接口。客户端代码只与适配器交互,而适配器负责将请求适配到旧类。
优点:
- 允许不兼容的类一起工作
- 提高可重用性,因为它可以使旧类与新系统集成
- 提高灵活性,允许轻松更改适配的类
代码示例:
interface Target {
operation(): void;
}
class Adaptee {
public specificOperation() {
console.log("Adaptee specificOperation");
}
}
class Adapter implements Target {
private adaptee: Adaptee;
constructor(adaptee: Adaptee) {
this.adaptee = adaptee;
}
public operation() {
this.adaptee.specificOperation();
}
}
// 使用适配器模式
const target: Target = new Adapter(new Adaptee());
target.operation();
装饰器模式
装饰器模式允许你动态地向现有对象添加新功能。它创建一个装饰器类,该类包装现有对象,并添加额外的行为。
客户端代码只与装饰器交互,而装饰器负责将请求委托给原始对象并添加额外的行为。
优点:
- 允许在不修改现有对象的情况下添加新功能
- 提高灵活性,允许轻松组合和更改装饰器
- 提高可扩展性,因为它允许轻松添加新功能
代码示例:
class Component {
public operation(): void {
console.log("Component operation");
}
}
class Decorator implements Component {
private component: Component;
constructor(component: Component) {
this.component = component;
}
public operation() {
this.component.operation();
console.log("Decorator operation");
}
}
// 使用装饰器模式
const component: Component = new Component();
const decorator: Decorator = new Decorator(component);
decorator.operation();
代理模式
代理模式创建一个代理类,该代理类代表另一个对象。它允许你控制对对象的访问,并为对象添加额外的功能。
代理模式通常用于保护对象免受不当访问、添加安全性或提高性能。客户端代码只与代理交互,而代理负责将请求委托给原始对象。
优点:
- 控制对对象的访问
- 提高安全性,因为它可以验证对对象的请求
- 提高性能,因为它可以缓存对象或提供其他优化
代码示例:
class Subject {
public request(): void {
console.log("Subject request");
}
}
class Proxy implements Subject {
private subject: Subject;
constructor(subject: Subject) {
this.subject = subject;
}
public request() {
console.log("Proxy request");
this.subject.request();
}
}
// 使用代理模式
const subject: Subject = new Subject();
const proxy: Proxy = new Proxy(subject);
proxy.request();
桥接模式
桥接模式将抽象部分与实现部分分离。抽象部分定义接口,而实现部分提供具体实现。这允许你独立更改抽象和实现,提高代码的灵活性。
桥接模式创建一个抽象类,该类有一个指向实现类的引用。客户端代码只与抽象类交互,而抽象类负责将请求委托给实现类。
优点:
- 分离抽象和实现,提高灵活性
- 减少耦合性,因为它允许你独立更改抽象和实现
- 提高可扩展性,因为它允许你轻松添加新抽象或实现
代码示例:
abstract class Abstraction {
protected implementor: Implementor;
constructor(implementor: Implementor) {
this.implementor = implementor;
}
public abstract operation(): void;
}
class ConcreteAbstraction1 extends Abstraction {
public operation(): void {
console.log("ConcreteAbstraction1 operation");
this.implementor.operation();
}
}
class ConcreteAbstraction2 extends Abstraction {
public operation(): void {
console.log("ConcreteAbstraction2 operation");
this.implementor.operation();
}
}
interface Implementor {
public operation(): void;
}
class ConcreteImplementorA implements Implementor {
public operation() {
console.log("ConcreteImplementorA operation");
}
}
class ConcreteImplementorB implements Implementor {
public operation() {
console.log("ConcreteImplementorB operation");
}
}
// 使用桥接模式
const abstraction1: Abstraction = new ConcreteAbstraction1(new ConcreteImplementorA());
abstraction1.operation();
const abstraction2: Abstraction = new ConcreteAbstraction2(new ConcreteImplementorB());
abstraction2.operation();
结论
外观、适配器、装饰器、代理和桥接模式是强大的结构型设计模式,可用于解决各种软件开发问题。它们通过提供可重用的解决方案来提高代码的可重用性、灵活性、可扩展性和可维护性。通过使用这些模式,你可以构建更强大、更灵活的应用程序。
常见问题解答
-
什么是设计模式?
答:设计模式是可重用的解决方案,用于解决常见软件开发问题。 -
什么是结构型设计模式?
答:结构型设计模式专注于类和对象的组合,以创建灵活且可维护的代码。 -
外观模式有什么好处?
答:外观模式简化了客户端与子系统之间的通信,提高了灵活性和可维护性。 -
适配器模式如何工作?
答:适配器模式将旧接口转换为新接口,允许不兼容的类一起工作。 -
装饰器模式如何添加新功能?
答:装饰器模式将现有对象包装在一个新类中,该新类添加了额外的行为。