如何学习设计模式
对于稳定点采用对父类进行抽象 子类去继承复写基类方法
对于变化点是通过扩展(继承和组合去实现
public:是用户可访问接口
private:用户和子类均不可访问 只有该类自己可访问
protected:用户不可访问接口 子类可以访问
virtual:虚方法前缀 可让该方法在继承父类后复写父类中的方法
xxx *zz = new yyy;
xxx:基类指针
yyy:复写流程
早绑定是指基类指针中没有虚函数 会将yyy强制转换为xxx类型 早绑定实际上就是强制转换
晚绑定 实际指向yyy
使用多态迭代进行代码更新 不改变基类 在继承的基础上进行增加修改
模板方法
里氏替代
子类型必须能够替换掉它的父类型;主要出现在子类覆盖父类实 现,原来使用父类型的程序可能出现错误;覆盖了父类方法却没 有实现父类方法的职责;
如何扩展(重要
实现子类继承基类,复写子流程
通过多态调用
未使用模板代码:
#include <iostream>
using namespace std;
// 设计原则
// 1. 设计原则演变过来的 2.符合设计原则的代码,只需要修改少量代码就可以演变成设计模式
// 接口隔离原则 1. 类封装 权限限定词来实现 2. 类与类依赖 接口(依赖注入)
// 最小知道原则
// 破坏了哪些设计原则:
// 单一职责(变化方向) 封装
// 开闭原则 对扩展开放 对修改关闭
// 扩展方式:继承,多态组合
class ZooShow {
public:
ZooShow(int type = 1) : _type(type) {}
public:
void Show() {
if (Show0())
PlayGame();
Show1();
Show2();
Show3();
}
private:
void PlayGame() {
cout << "after Show0, then play game" << endl;
}
bool Show0() {
if (_type == 1) {
//
return true;
} else if (_type == 2 ) {
// ...
} else if (_type == 3) {
}
cout << _type << " show0" << endl;
return true;
}
void Show1() {
if (_type == 1) {
cout << _type << " Show1" << endl;
} else if (_type == 2) {
cout << _type << " Show1" << endl;
} else if (_type == 3) {
}
}
void Show2() {
if (_type == 20) {
}
cout << "base Show2" << endl;
}
void Show3() {
if (_type == 1) {
cout << _type << " Show1" << endl;
} else if (_type == 2) {
cout << _type << " Show1" << endl;
}
}
private:
int _type;
};
int main () {
ZooShow *zs = new ZooShow(1);
zs->Show();
return 0;
}
模板代码如下:
#include <iostream>
using namespace std;
// 开闭 原有类
class ZooShow {
public:
void Show() {
// 如果子表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接进入下一个子表演流程
if (Show0())
PlayGame();
Show1();
Show2();
Show3();
}
private:
void PlayGame() {
cout << "after Show0, then play game" << endl;
}
bool expired;
// 对其他用户关闭,但是子类开放的
protected:
virtual bool Show0() {
cout << "show0" << endl;
if (! expired) {
return true;
}
return false;
}
virtual void Show2() {
cout << "show2" << endl;
}
virtual void Show1() {
}
virtual void Show3() {
}
};
// 框架
// 模板方法模式 如何扩展
class ZooShowEx10 : public ZooShow {
protected:
virtual void Show0() {
if (! expired) {
return true;
}
return false;
}
}
class ZooShowEx1 : public ZooShow {
protected:
virtual bool Show0() {
cout << "ZooShowEx1 show0" << endl;
if (! expired) { // 里氏替换
return true;
}
return false;
}
virtual void Show2(){
cout << "show3" << endl;
}
};
class ZooShowEx2 : public ZooShow {
protected:
virtual void Show1(){
cout << "show1" << endl;
}
virtual void Show2(){
cout << "show3" << endl;
}
};
class ZooShowEx3 : public ZooShow {
protected:
virtual void Show1(){
cout << "show1" << endl;
}
virtual void Show3(){
cout << "show3" << endl;
}
virtual void Show4() {
//
}
};
/*
*//调用
int main () {
ZooShow *zs = new ZooShowEx10; // 晚绑定还是早绑定
// ZooShow *zs1 = new ZooShowEx1;
// ZooShow *zs2 = new ZooShowEx2;
zs->Show();
return 0;
}
观察者模式
定义对象间的一种一对多(变化)的依赖关系,以便当一个对 象(Subject)的状态发生改变时,所有依赖于它的对象都得到通 知并自动更新。
接口隔离还有一个是容器存储接口
没有使用模式的代码:
class DisplayA {
public:
void Show(float temperature);
};
class DisplayB {
public:
void Show(float temperature);
};
class DisplayC {
public:
void Show(float temperature);
}
class WeatherData {
};
class DataCenter {
public:
void TempNotify() {
DisplayA *da = new DisplayA;
DisplayB *db = new DisplayB;
DisplayC *dc = new DisplayC;
// DisplayD *dd = new DisplayD;
float temper = this->CalcTemperature();
da->Show(temper);
db->Show(temper);
dc->Show(temper);
dc->Show(temper);
}
private:
float CalcTemperature() {
WeatherData * data = GetWeatherData();
// ...
float temper/* = */;
return temper;
}
WeatherData * GetWeatherData(); // 不同的方式
};
int main() {
DataCenter *center = new DataCenter;
center->TempNotify();
return 0;
}
使用了模式代码:
#include <list>
#include <algorithm>
using namespace std;
//
class IDisplay {
public:
virtual void Show(float temperature) = 0;
virtual ~IDisplay() {}
};
class DisplayA : public IDisplay {
public:
virtual void Show(float temperature) {
cout << "DisplayA Show" << endl;
}
private:
void jianyi();
};
class DisplayB : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayB Show" << endl;
}
};
class DisplayC : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayC Show" << endl;
}
};
class DisplayD : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayC Show" << endl;
}
};
class WeatherData {
};
// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
class DataCenter {
public:
void Attach(IDisplay * ob) {
//
}
void Detach(IDisplay * ob) {
//
}
void Notify() {
float temper = CalcTemperature();
for (auto iter : obs) {
iter.Show(temper);
}
}
// 接口隔离
private:
WeatherData * GetWeatherData();
float CalcTemperature() {
WeatherData * data = GetWeatherData();
// ...
float temper/* = */;
return temper;
}
std::list<IDisplay*> obs;
};
int main() {
// 单例模式
DataCenter *center = new DataCenter;
// ... 某个模块
IDisplay *da = new DisplayA();
center->Attach(da);
// ...
IDisplay *db = new DisplayB();
center->Attach(db);
IDisplay *dc = new DisplayC();
center->Attach(dc);
center->Notify();
//-----
center->Detach(db);
center->Notify();
//....
center->Attach(dd);
center->Notify();
return 0;
}
如何扩展
class DisplayD : public IDisplay{
public:
virtual void Show(float temperature) {
cout << "DisplayC Show" << endl;
}
};
/......
//....
center->Attach(dd);
策略模式
代码结构
1.接口
2.封装 -->调用关系
3.依赖注入
4.调用方式
未使用策略代码:
enum VacationEnum {
VAC_Spring,
VAC_QiXi,
VAC_Wuyi,
VAC_GuoQing,
VAC_ShengDan,
};
class Promotion {
VacationEnum vac;
public:
double CalcPromotion(){
if (vac == VAC_Spring {
// 春节
}
else if (vac == VAC_QiXi) {
// 七夕
}
else if (vac == VAC_Wuyi) {
// 五一
}
else if (vac == VAC_GuoQing) {
// 国庆
}
else if (vac == VAC_ShengDan) {
}
}
};
使用策略(摆脱if else 降低耦合
class Context {
};
// 稳定点:抽象去解决它
// 变化点:扩展(继承和组合)去解决它
class ProStategy {
public:
virtual double CalcPro(const Context &ctx) = 0;
virtual ~ProStategy();
};
// cpp
class VAC_Spring : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_QiXi : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_QiXi1 : public VAC_QiXi {
public:
virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_Wuyi : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_GuoQing : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class VAC_Shengdan : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
class Promotion {
public:
Promotion(ProStategy *sss) : s(sss){}
~Promotion(){}
double CalcPromotion(const Context &ctx){
return s->CalcPro(ctx);
}
private:
ProStategy *s;
};
int main () {
Context ctx;
ProStategy *s = new VAC_QiXi1();
Promotion *p = new Promotion(s);
p->CalcPromotion(ctx);
return 0;
}
如何扩展
//继承基类并复写方法
class VAC_Shengdan : public ProStategy {
public:
virtual double CalcPro(const Context &ctx){}
};
//使用 通过依赖注入调用对应函数
int main () {
Context ctx;
ProStategy *s = new VAC_QiXi1();
Promotion *p = new Promotion(s);
p->CalcPromotion(ctx);
return 0;
}