桥接模式 & 与装饰器模式的比较

桥接模式(Bridge Pattern)是一种结构型设计模式,它通过将抽象部分与实现部分分离,使得两者可以独立变化。桥接模式主要用于解决某些类的层次结构过于复杂的问题,允许将抽象和具体实现解耦,从而增强系统的灵活性和可扩展性。

特点

  1. 分离抽象和实现:桥接模式将抽象部分与实现部分分开,使得它们可以独立变化。
  2. 扩展性:可以通过增加新的实现类或者抽象类来扩展系统,而不需要修改现有代码。
  3. 避免多重继承:通过使用桥接模式,可以减少由于多重继承所带来的复杂性。

场景

桥接模式适用于以下场景:

  • 当一个类有多个变化的维度时,使用桥接模式可以将这些维度分离开来。
  • 当需要在多个抽象和实现之间进行组合时,可以使用桥接模式。
  • 在需要避免类的层次结构过于复杂的情况下,桥接模式可以帮助简化设计。

举例

假设我们有一个图形绘制程序,支持不同的图形(如圆形和正方形)以及不同的颜色(如红色和蓝色)。我们可以使用桥接模式来将图形与颜色分离。

#include <iostream>

// 实现接口
class Color {
public:
    virtual void applyColor() = 0; // 纯虚函数
};

// 具体实现类
class Red : public Color {
public:
    void applyColor() override {
        std::cout << "Applying red color." << std::endl;
    }
};

class Blue : public Color {
public:
    void applyColor() override {
        std::cout << "Applying blue color." << std::endl;
    }
};

// 抽象类
class Shape {
protected:
    Color* color; // 持有一个颜色的引用

public:
    Shape(Color* c) : color(c) {}
    virtual void draw() = 0; // 纯虚函数
};

// 具体抽象类
class Circle : public Shape {
public:
    Circle(Color* c) : Shape(c) {}

    void draw() override {
        std::cout << "Drawing Circle. ";
        color->applyColor();
    }
};

class Square : public Shape {
public:
    Square(Color* c) : Shape(c) {}

    void draw() override {
        std::cout << "Drawing Square. ";
        color->applyColor();
    }
};

int main() {
    Color* red = new Red();
    Color* blue = new Blue();

    Shape* circle = new Circle(red);
    Shape* square = new Square(blue);

    circle->draw(); // 输出:Drawing Circle. Applying red color.
    square->draw(); // 输出:Drawing Square. Applying blue color.

    // 清理内存
    delete circle;
    delete square;
    delete red;
    delete blue;

    return 0;
}

 装饰器模式代码举例

#include <iostream>
#include <string>

// 基础饮品接口
class Beverage {
public:
    virtual std::string getDescription() = 0; // 获取描述
    virtual double cost() = 0; // 获取价格
};

// 具体饮品类
class Coffee : public Beverage {
public:
    std::string getDescription() override {
        return "Coffee";
    }

    double cost() override {
        return 5.0; // 咖啡的基本价格
    }
};

// 装饰器基类
class CondimentDecorator : public Beverage {
protected:
    Beverage* beverage; // 被装饰的饮品

public:
    CondimentDecorator(Beverage* b) : beverage(b) {}
};

// 具体装饰器类
class Milk : public CondimentDecorator {
public:
    Milk(Beverage* b) : CondimentDecorator(b) {}

    std::string getDescription() override {
        return beverage->getDescription() + ", Milk";
    }

    double cost() override {
        return beverage->cost() + 1.5; // 加入牛奶的价格
    }
};

class Sugar : public CondimentDecorator {
public:
    Sugar(Beverage* b) : CondimentDecorator(b) {}

    std::string getDescription() override {
        return beverage->getDescription() + ", Sugar";
    }

    double cost() override {
        return beverage->cost() + 0.5; // 加入糖的价格
    }
};

int main() {
    Beverage* coffee = new Coffee();
    std::cout << coffee->getDescription() << " $" << coffee->cost() << std::endl;

    // 添加牛奶
    Beverage* milkCoffee = new Milk(coffee);
    std::cout << milkCoffee->getDescription() << " $" << milkCoffee->cost() << std::endl;

    // 添加糖
    Beverage* milkSugarCoffee = new Sugar(milkCoffee);
    std::cout << milkSugarCoffee->getDescription() << " $" << milkSugarCoffee->cost() << std::endl;

    // 清理内存
    delete milkSugarCoffee;
    delete milkCoffee;
    delete coffee;

    return 0;
}

与装饰器模式的区别

装饰器模式(Decorator Pattern)也是一种结构型设计模式,它允许在运行时动态地向对象添加额外的职责。装饰器模式通常用于为对象添加新功能,而无需改变其结构。

主要区别

  1. 目的不同

    • 桥接模式的主要目的是将抽象与实现分开,使它们独立变化。
    • 装饰器模式的主要目的是在不改变对象的情况下,动态地为对象添加新功能。
  2. 结构不同

    • 在桥接模式中,抽象类和实现类都是独立的,可以通过组合关系来使用。
    • 在装饰器模式中,装饰器类通常是通过继承被装饰的类来实现的,增强了对象的功能。
  3. 使用场景

    • 桥接模式适合于需要对多个维度进行扩展的场景。
    • 装饰器模式适合于需要动态增加功能的场景。

总结

桥接模式和装饰器模式在设计思想和应用场景上有着明显的区别。桥接模式侧重于结构的解耦,使得不同的实现可以独立变化,而装饰器模式则侧重于功能的扩展,使得对象在运行时可以动态地增加新行为。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值