跳至主要內容

桥接模式

约 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();

上次编辑于: