修饰模式,参考:
通过使用修饰模式,可以在运行时扩充一个类的功能。原理是:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
修饰模式是类继承的另外一种选择。类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
自己参照着写的一份代码:
main.cpp
#include <iostream>
using namespace std;
#include "plane.h"
#include "fighter.h"
#include "bomber.h"
#include "decorator_weapon.h"
#include "missile_decorator.h"
#include "laser_decorator.h"
#include "well_armed_decorator.h"
int main() {
//plane pl; // error: cannot instantiate with an abstract class
//plane* primary_fighter, primary_bomber; // error: the compiler regard the second one as a plane class but not a pointer
plane *primary_fighter, *primary_bomber; // to use a pointer pointing to an abstract class is ok
plane *equipped_missile_fighter, *equipped_missile_bomber;
plane *equipped_laser_fighter, *equipped_laser_bomber;
plane *well_armed_fighter, *well_armed_bomber;
plane *well_armed_fighter_2, *well_armed_bomber_2;
primary_fighter = new fighter();
primary_bomber = new bomber();
primary_fighter->shot();
cout << endl;
primary_bomber->shot();
cout << endl;
cout << endl;
equipped_missile_fighter = new missile_decorator(primary_fighter);
equipped_missile_bomber = new missile_decorator(primary_bomber);
equipped_missile_fighter->shot();
cout << endl;
equipped_missile_bomber->shot();
cout << endl;
cout << endl;
equipped_laser_fighter = new laser_decorator(primary_fighter);
equipped_laser_bomber = new laser_decorator(primary_bomber);
equipped_laser_fighter->shot();
cout << endl;
equipped_laser_bomber->shot();
cout << endl;
cout << endl;
well_armed_fighter = new laser_decorator(equipped_missile_fighter);
well_armed_bomber = new missile_decorator(equipped_laser_bomber);
well_armed_fighter->shot();
cout << endl;
well_armed_bomber->shot();
cout << endl;
cout << endl;
//my personal understanding of decorator is the well_armed_decorator class packs up the fighter class, and well_armed_fighter_2 is just a decorated primary_fighter, we can add more function to the original class, like shotting with missile and laser, but also and use the function of the original class, like simply shotting
well_armed_fighter_2 = new well_armed_decorator(primary_fighter);
well_armed_bomber_2 = new well_armed_decorator(primary_bomber);
primary_fighter->shot(); // shotting without decorator
cout << endl;
well_armed_fighter_2->shot(); // shotting with decorator
cout << endl;
well_armed_bomber_2->shot();
cout << endl;
cout << endl;
return 0;
}
plane.h
#ifndef __PLANE_H
#define __PLANE_H
#include <iostream>
using namespace std;
class plane {
public:
plane() {
cout << "a plane has been made." << endl;
}
plane(plane* pl) {
cout << "a plane has been made." << endl;
}
virtual void shot() = 0;
};
#endif
fighter.h
#ifndef __FIGHTER_H
#define __FIGHTER_H
#include "plane.h"
#include <iostream>
using namespace std;
class fighter: public plane {
public:
fighter() {
cout << "a fighter has been made." << endl;
}
void shot() {
cout << "fighter is shotting with gun ";
}
};
#endif
bomber.h
#ifndef __BOMBER_H
#define __BOMBER_H
#include "plane.h"
#include <iostream>
using namespace std;
class bomber: public plane {
public:
bomber() {
cout << "a bomber has been made." << endl;
}
void shot() {
cout << "bomber is shotting with gun ";
}
};
#endif
decorator_weapon.h
#ifndef __DECORATOR_WEAPON_H
#define __DECORATOR_WEAPON_H
#include "plane.h"
#include <iostream>
using namespace std;
class decorator_weapon: public plane {
protected:
plane* pl;
public:
decorator_weapon(plane* pl): pl(pl) {
cout << "a weapon has been made." << endl;
}
void shot() {
pl->shot();
}
};
#endif
missile_decorator.h
#ifndef __MISSILE_DECORATOR_H
#define __MISSILE_DECORATOR_H
#include "decorator_weapon.h"
#include <iostream>
using namespace std;
class missile_decorator: public decorator_weapon {
public:
missile_decorator(plane* pl): decorator_weapon(pl) {
cout << "a missile has been made." << endl;
}
void shot() {
pl->shot();
cout << "and missile ";
}
};
#endif
laser_decorator.h
#ifndef __LASER_DECORATOR_H
#define __LASER_DECORATOR_H
#include "decorator_weapon.h"
#include <iostream>
using namespace std;
class laser_decorator: public decorator_weapon {
public:
laser_decorator(plane* pl): decorator_weapon(pl) {
cout << "a laser has been made." << endl;
}
void shot() {
pl->shot();
cout << "and laser ";
}
};
#endif
well_armed_decorator.h
#ifndef __WELL_ARMED_DECORATOR_H
#define __WELL_ARMED_DECORATOR_H
#include "decorator_weapon.h"
#include "missile_decorator.h"
#include "laser_decorator.h"
class well_armed_decorator: public decorator_weapon {
public:
well_armed_decorator(plane* pl): decorator_weapon(pl) {
cout << "a missile and a laser has been made." << endl;
}
void shot() {
pl->shot();
cout << "and laser and missile";
}
};
#endif