桥接模式
约 608 字
桥接模式
核心思想
桥接模式用于将抽象部分与实现部分分离,使它们都可以独立地变化。
典型用例
数据库抽象访问
在需要支持多种数据库的应用中,桥接模式可以用于将业务逻辑(抽象部分)与数据库访问层(实现部分)分离,使得更换数据库时不需要修改业务逻辑。
在这个例子中,DataService及其子类表示抽象部分,负责定义高层的业务逻辑。Database接口及其实现表示实现部分,负责具体的数据库操作。这使得更换数据库变得简单,因为业务逻辑层不需要知道具体使用的是哪种数据库。
// npm run code src/code/design-pattern/bridge/database-access.ts
export {};
// 数据库访问接口
interface Database {
connect(): void;
query(sql: string): any;
disconnect(): void;
}
// 具体数据库实现
class MySqlDatabase implements Database {
connect(): void {
console.log('Connecting to MySQL database.');
}
query(sql: string): any {
console.log(`Querying: ${sql}`);
// 实现查询逻辑...
}
disconnect(): void {
console.log('Disconnecting from MySQL database.');
}
}
class PostgreSqlDatabase implements Database {
connect(): void {
console.log('Connecting to PostgreSQL database.');
}
query(sql: string): any {
console.log(`Querying: ${sql}`);
// 实现查询逻辑...
}
disconnect(): void {
console.log('Disconnecting from PostgreSQL database.');
}
}
// 创建一个抽象类持有数据库访问接口的引用,并定义与数据库操作相关的业务逻辑
abstract class DataService {
protected database: Database;
constructor(database: Database) {
this.database = database;
}
abstract processData(): void;
}
class UserDataService extends DataService {
processData(): void {
this.database.connect();
// 业务逻辑,例如查询用户数据
this.database.query("SELECT * FROM users");
this.database.disconnect();
}
}
class ProductDataService extends DataService {
processData(): void {
this.database.connect();
// 业务逻辑,例如查询产品数据
this.database.query("SELECT * FROM products");
this.database.disconnect();
}
}
const mysqlDatabase = new MySqlDatabase();
const postgresDatabase = new PostgreSqlDatabase();
const userService = new UserDataService(mysqlDatabase);
userService.processData(); // 使用 MySQL 数据库处理用户数据
const productService = new ProductDataService(postgresDatabase);
productService.processData(); // 使用 PostgreSQL 数据库处理产品数据
多维度变化的系统
当一个系统有多维变化时可以使用桥接模式。例如:一个软件产品有不同的版本,每个版本有不同的操作系统支持,桥接模式允许将这些变化的维度(产品版本和操作系统)独立开来,实现解耦。
// npm run code src/code/design-pattern/bridge/multi-dimensional-system.ts
export {};
// 操作系统接口
interface OperatingSystem {
getName(): string;
}
// 具体的操作系统类
class Windows implements OperatingSystem {
getName(): string {
return 'Windows';
}
}
class MacOS implements OperatingSystem {
getName(): string {
return 'MacOS';
}
}
class Linux implements OperatingSystem {
getName(): string {
return 'Linux';
}
}
// 软件产品抽象类
abstract class SoftwareProduct {
protected os: OperatingSystem;
constructor(os: OperatingSystem) {
this.os = os;
}
abstract getVersion(): string;
abstract run(): void;
}
// 具体的软件产品类
class ProductA extends SoftwareProduct {
getVersion(): string {
return 'ProductA Version 1.0';
}
run(): void {
console.log(`${this.getVersion()} running on ${this.os.getName()}`);
}
}
class ProductB extends SoftwareProduct {
getVersion(): string {
return 'ProductB Version 2.0';
}
run(): void {
console.log(`${this.getVersion()} running on ${this.os.getName()}`);
}
}
// 使用示例
const windows = new Windows();
const productAOnWindows = new ProductA(windows);
productAOnWindows.run();
const linux = new Linux();
const productBOnLinux = new ProductB(linux);
productBOnLinux.run();
跨平台应用开发
在开发跨平台应用时,桥接模式可以用来分离抽象的用户界面与具体的平台实现,使得同一套用户界面代码可以在不同平台上云霄。
// npm run code src/code/design-pattern/bridge/develop-cross-platform-applications.ts
export {};
// 平台接口
interface Platform {
renderUI(): void;
}
// 具体的平台类
class WindowsPlatform implements Platform {
renderUI(): void {
console.log('Rendering UI in Windows style');
}
}
class MacOSPlatform implements Platform {
renderUI(): void {
console.log('Rendering UI in MacOS style');
}
}
class LinuxPlatform implements Platform {
renderUI(): void {
console.log('Rendering UI in Linux style');
}
}
// 用户界面抽象类
abstract class UserInterface {
protected platform: Platform;
constructor(platform: Platform) {
this.platform = platform;
}
abstract draw(): void;
}
// 具体的用户界面类
class ApplicationUI extends UserInterface {
draw(): void {
console.log('Application UI is being drawn');
this.platform.renderUI();
}
}
// 使用示例
const windowsPlatform = new WindowsPlatform();
const appUIOnWindows = new ApplicationUI(windowsPlatform);
appUIOnWindows.draw();
const macPlatform = new MacOSPlatform();
const appUIOnMac = new ApplicationUI(macPlatform);
appUIOnMac.draw();
const linuxPlatform = new LinuxPlatform();
const appUIOnLinux = new ApplicationUI(linuxPlatform);
appUIOnLinux.draw();
驱动程序开发
在开发硬件驱动程序时,桥接模式可以用来将驱动程序的高层逻辑(抽象部分)与底层硬件操作(实现部分)分离。这种方式使得驱动程序可以独立于硬件进行开发和测试,从而提高了代码的可维护性和可扩展性。
// npm run code src/code/design-pattern/bridge/driver-development.ts
export {};
// 硬件接口
interface HardwareInterface {
sendCommand(command: string): void;
receiveData(): string;
}
// 具体的硬件类
class KeyboardHardware implements HardwareInterface {
sendCommand(command: string): void {
console.log(`Sending '${command}' to Keyboard`);
}
receiveData(): string {
return 'Keyboard data';
}
}
class MouseHardware implements HardwareInterface {
sendCommand(command: string): void {
console.log(`Sending '${command}' to Mouse`);
}
receiveData(): string {
return 'Mouse data';
}
}
// 驱动程序抽象类
abstract class Driver {
protected hardware: HardwareInterface;
constructor(hardware: HardwareInterface) {
this.hardware = hardware;
}
abstract execute(): void;
}
// 具体的驱动程序类
class KeyboardDriver extends Driver {
execute(): void {
console.log('Executing Keyboard driver logic');
this.hardware.sendCommand('keyboard-init');
console.log(`Received: ${this.hardware.receiveData()}`);
}
}
class MouseDriver extends Driver {
execute(): void {
console.log('Executing Mouse driver logic');
this.hardware.sendCommand('mouse-init');
console.log(`Received: ${this.hardware.receiveData()}`);
}
}
// 使用示例
const keyboardHardware = new KeyboardHardware();
const keyboardDriver = new KeyboardDriver(keyboardHardware);
keyboardDriver.execute();
const mouseHardware = new MouseHardware();
const mouseDriver = new MouseDriver(mouseHardware);
mouseDriver.execute();
图形和渲染系统
在图形和渲染系统中,可以使用桥接模式来分离抽象的图形对象和具体的渲染API(如OpenGL、DirectX),使得图形对象不直接依赖于特定的渲染技术。这样的设计使得图形对象不直接依赖于特定的渲染技术,从而增强了系统的可扩展性和灵活性。
// npm run code src/code/design-pattern/bridge/graphics-and-rendering-systems.ts
export {};
// 渲染API接口
interface RenderAPI {
renderShape(shape: string): void;
}
// 具体的渲染API类
class OpenGLAPI implements RenderAPI {
renderShape(shape: string): void {
console.log(`Rendering ${shape} with OpenGL`);
}
}
class DirectXAPI implements RenderAPI {
renderShape(shape: string): void {
console.log(`Rendering ${shape} with DirectX`);
}
}
// 图形抽象类
abstract class Shape {
protected api: RenderAPI;
constructor(api: RenderAPI) {
this.api = api;
}
abstract draw(): void;
}
// 具体的图形类
class Circle extends Shape {
draw(): void {
this.api.renderShape('Circle');
}
}
class Rectangle extends Shape {
draw(): void {
this.api.renderShape('Rectangle');
}
}
// 使用示例
const openGL = new OpenGLAPI();
const circle = new Circle(openGL);
circle.draw();
const directX = new DirectXAPI();
const rectangle = new Rectangle(directX);
rectangle.draw();