装饰器模式属于结构型模式,主要用于在不增加子类的情况下增强一个类的功能。
假如有一个游戏基类,派生出篮球和足球两个独立运动,一个人要么打篮球要么踢足球,但是如果一个人既要打篮球又要踢足球呢?这样写?
struct Game {
virtual ~Game() {}
virtual void Play() = 0;
};
struct BasketBall : public Game {
BasketBall() {}
void Play() override {
std::cout << "play basketball \n";
}
};
struct SocketBasketBall : public Game {
SocketBasketBall() {}
void Play() override {
std::cout << "play SocketBall \n";
std::cout << "play BasketBall \n";
}
};
int main() {
Game* ball = new SocketBasketBall();
ball->Play();
return 0;
}
如果有一个人又要打篮球又要踢足球又要打乒乓球呢,那还需要扩展出好多子类,显然不太灵活。有没有方法可以在不增加很多子类的情况下扩展类的功能呢?
这就用到了装饰器模式,装饰器模式可以增强现有类的功能,可以看如下代码实现:
struct Game {
virtual ~Game() {}
virtual void Play() = 0;
};
struct BasketBallDecorator : public Game {
BasketBallDecorator() {}
BasketBallDecorator(Game* game) { game_ = game; }
void Play() override {
std::cout << "play basketball \n";
if (game_) game_->Play();
}
private:
Game* game_;
};
struct SocketBallDecorator : public Game {
SocketBallDecorator() {}
SocketBallDecorator(Game* game) { game_ = game; }
void Play() override {
std::cout << "play SocketBall \n";
if (game_) game_->Play();
}
private:
Game* game_;
};
int main() {
Game* ball = new BasketBallDecorator();
ball = new SocketBallDecorator(ball); // 暂时忽略内存泄漏
ball->Play();
return 0;
}
这里装饰器类和原始类继承同样的父类,这样就可以对原始类嵌套多个装饰器类,起到增强类功能的作用。
装饰器模式和代理模式有个重要区别就是装饰器模式是对一个类的增强,附加的是跟原始类有关的功能,而代理模式附加的是与原始类无关的额外功能。
当我们需要扩展一个类的功能或者需要动态增加功能时,可以考虑使用装饰器模式。
更多文章,请关注我的V X 公 主 号:程序喵大人,欢迎交流。
网友评论