链接:C++ 设计模式
链接:C++ 设计模式 - 桥接模式
装饰模式(Decorator Pattern)是一种结构型设计模式,它允许向一个现有的对象添加新的功能,同时又不改变其结构。装饰模式通过创建一个装饰类来包装原始类,从而在保持类接口不变的情况下,动态地扩展对象的功能。
1.适用场景
- 需要动态扩展对象的功能:当需要在运行时动态地为对象添加功能,而不是在编译时确定这些功能时。
- 功能可以按需组合:当对象的功能可以通过多种方式组合,并且这些组合是动态变化的。
- 避免类爆炸:如果使用继承来扩展功能,会导致类的数量急剧增加,因为每种功能组合都需要一个新的子类。装饰模式通过组合装饰器来避免这个问题。
2.实现步骤
- 定义组件接口:定义一个接口,描述基本组件的行为。
- 实现具体组件:实现基本组件类,提供组件的基本功能。
- 定义装饰器基类:创建一个装饰器基类,继承自组件接口,并持有一个组件对象的引用。
- 实现具体装饰器:实现具体装饰器类,继承自装饰器基类,并在扩展功能的方法中调用被装饰的组件对象的方法。
- 动态组合装饰器:在客户端代码中,动态地将装饰器组合在一起,扩展组件的功能。
3.代码示例
以机器人的任务扩展作为示例。
3.1.组件接口
class Robot {
public:
virtual ~Robot() = default;
virtual void performTask() = 0;
};
3.2.基本组件
// 具备基本功能
class BasicRobot : public Robot {
public:
void performTask() override { std::cout << "Performing basic tasks." << std::endl; }
};
3.3.装饰器基类
// 继承自组件接口
class RobotDecorator : public Robot {
public:
RobotDecorator(std::shared_ptr<Robot> robot) : decoratedRobot(robot) {}
void performTask() override { decoratedRobot->performTask(); }
protected:
std::shared_ptr<Robot> decoratedRobot;
};
3.4.具体装饰器
// 具体装饰器1:添加播放音乐功能
class MusicPlayerDecorator : public RobotDecorator {
public:
MusicPlayerDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}
void performTask() override {
RobotDecorator::performTask();
playMusic();
}
private:
void playMusic() { std::cout << "Playing music." << std::endl; }
};
// 具体装饰器2:添加拍照功能
class CameraDecorator : public RobotDecorator {
public:
CameraDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}
void performTask() override {
RobotDecorator::performTask();
takePhoto();
}
private:
void takePhoto() { std::cout << "Taking a photo." << std::endl; }
};
// 具体装饰器3:添加导航功能
class NavigationDecorator : public RobotDecorator {
public:
NavigationDecorator(std::shared_ptr<Robot> robot) : RobotDecorator(robot) {}
void performTask() override {
RobotDecorator::performTask();
navigate();
}
private:
void navigate() { std::cout << "Navigating to the destination." << std::endl; }
};
3.5.动态组合
int main() {
// 创建一个基本机器人
std::shared_ptr<Robot> basicRobot = std::make_shared<BasicRobot>();
// 添加播放音乐功能
std::shared_ptr<Robot> musicPlayerRobot = std::make_shared<MusicPlayerDecorator>(basicRobot);
// 添加播放音乐和拍照功能
std::shared_ptr<Robot> cameraRobot = std::make_shared<CameraDecorator>(musicPlayerRobot);
// 添加播放音乐和导航功能
std::shared_ptr<Robot> fullFeaturedRobot = std::make_shared<NavigationDecorator>(musicPlayerRobot );
// 执行任务
std::cout << "Basic Robot:" << std::endl;
basicRobot->performTask();
std::cout << "\nMusic Player Robot:" << std::endl;
musicPlayerRobot->performTask();
std::cout << "\nCamera Robot:" << std::endl;
cameraRobot->performTask();
std::cout << "\nFull Featured Robot:" << std::endl;
fullFeaturedRobot->performTask();
return 0;
}
4.总结
装饰模式和桥接模式的区别:
- 装饰模式:动态地给对象添加职责,而不改变对象的接口。它通过创建一系列装饰器类来实现这些职责的扩展,从而在运行时灵活地扩展对象的功能。
- 桥接模式:将抽象部分与实现部分分离,使它们可以独立变化。它通过将抽象和实现放在不同的类层次结构中,并通过组合将它们连接起来,从而提高系统的灵活性和可扩展性。