栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

设计模式(C++的实现):模板方法 和 观察者模式

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

设计模式(C++的实现):模板方法 和 观察者模式

设计模式(C++)
设计模式依托于设计原则,最主要的是设计原则的理解,在设计模式中理解原则,使用原则尤为重要。
模式设计原则:
  • 依赖倒置原则:
    • 高层模块不应该依赖低层模块,两者都应该依赖抽象
    • 抽象不应该依赖具体实现,具体实现应该依赖于抽象
  • 开发封闭原则:
    • 一个类应该对扩展开发,对修改关闭
  • 面向接口编程:
    • 不将变量类型声明为某个特定的具体类,⽽是声明为某个接⼝。
    • 客户程序⽆需获知对象的具体类型,只需要知道对象所具有的接⼝。
    • 减少系统中各部分的依赖关系,从⽽实现“⾼内聚、松耦合”的类型设计⽅案
  • 封装变化点:
    • 将稳定点和变化点分离,扩展变化点;让稳定点与变化点实现层次分离。
  • 单一职责原则:
    • 一个类应该仅有一个引起它变化的原因
  • 里式替换原则:
    • ⼦类型必须能够替换掉它的⽗类型;主要出现在⼦类覆盖⽗类实现,原来使⽤⽗类型的程序可能出现错误;覆盖了⽗类⽅法却没实现⽗类⽅法的职责;
  • 接口隔离原则:
    • 不应该强迫客户依赖于他们不⽤的⽅法;
    • ⼀般⽤于处理⼀个类拥有⽐较多的接⼝,⽽这些接⼝涉及到很多职责;
  • 对象组合优于类继承
    • 继承耦合度高,组合耦合度低
设计模式 模板方法
  • 定义

    定义⼀个操作中的算法的⻣架 ,⽽将⼀些步骤延迟到⼦类中。 Template Method使得⼦类可以不改变⼀个算法的结构即可重定义该算法的某些特定步骤。 ——《 设计模式》 GoF

  • 背景

    某个品牌动物园,有⼀套固定的表演流程,但是其中有若⼲个表演⼦流程受欢迎程度⽐较低,希望将这⼏个表演流程创新,以尝试迭代更新表演流程;

  • 代码

class ZooShow{
public:
	void show(){//该类的职责,也是固定点
        show0();
        show1();
        show2();
        show3();
    }
protected://变化点,且接口分离原则,不能提供给客户他们不需要的接口
    virtual void show0(){
        cout << "show0()" << endl;
    };
    virtual void show1(){
        
    };
    virtual void show2(){
        cout << "show2()" << endl;
    };
    virtual void show3(){
        
    };
};

class ZooShowEs
:public ZoomShow
{
public:
    virtual void show1(){
      	cout << "ZoomShowEs::show1()" << endl;  
    }
    virtual void show3(){
        cout << "ZoomShowEs::show1()" << endl;  
    };
};
//反向调用:子类继承父类接口实现功能,最终父类去调用子类的函数
//此时高层即main函数中的流程,低层就是父类和子类,就是依赖倒置原则
int main(){
	ZooShow * p = new ZooShowEs();
    p->show();
}在这里插入代码片
  • 要点

    ⾮常常⽤的设计模式,⼦类可以复写⽗类的⼦流程,使⽗类的⼤流程更丰富;反向控制流程的典型应⽤;⽗类 protected 保护⼦类需要复写的⼦流程;这样⼦类的⼦流程只能⽗类来调⽤;充分体现了依赖倒置原则;

  • 本质

    通过固定算法⻣架来约束⼦类的⾏为;

  • 结构图

观察者模式
  • 定义

    定义对象间的⼀种⼀对多(变化)的依赖关系,以便当⼀个对象(Subject)的状态发⽣改变时,所有依赖于它的对象都得到通知并⾃动更新。 ——《 设计模式》 GoF

  • 背景

    ⽓象站发布⽓象资料给数据中⼼,数据中⼼经过处理,将⽓象信息更新到两个不同的显示终端(A 和B);

  • 代码

class DisplayA{
public:
    void Show(float temperature);
};
class DisplayB{
    void Show(float temperature);
};

class WeatherData{
    
};
class DataCenter{
public:
  	float CalcTemperature(){
        WeatherData * data = GetWeatherData();
        //...
        float temper;
        return temper;
    }  
private:
    WeatherData * GetWeatherData();
};

int main(){
    DataCenter *center = new DataCenter;
    DisplayA *da = new DisplayA();
    DisplayB *db = new DisplayB();
    float temper = center->CalcTemperture();
    da->Show(temper);
    db->Show(temper);
}



class IDisplay{
  	virtual void Show(float temperature) = 0;
};
class DisplayA
:public IDisplay
{
public:
    void Show(float temperature){
        cout << "DisplayA::Show()" << endl;
    }
};
class DisplayB
:public IDisplay
{
    void Show(float temperature){
        cout << "DisplayB::Show()" << endl;
    }
};

class WeatherData{
    
};
class DataCenter{
public:
    void Show(){
        CalcTemperature();
        for(auto iter = vec.begin();iter != vec.end(); ++iter){
            (*iter)->Show();
        }
    }
    void Attache(IDisplay* p);
    void Dttache(IDisplay* p);
protected://接口隔离原则,但其子类任然能够进行修改
  	virtual float CalcTemperature(){
        WeatherData * data = GetWeatherData();
        //...
        float temper;
        return temper;
    }  
private:
    vector vec;
    WeatherData * GetWeatherData();
};

int main(){
    DataCenter *center = new DataCenter;
    IDisplay *da = new DisplayA();
    IDisplay *db = new DisplayB();
 	cecter->Attache(da);  
    cecter->Attache(da); 
	center->Show();
}在这里插入代码片
  • 要点

    观察者模式使得我们可以独⽴地改变⽬标与观察者,从⽽使⼆者之间的关系松耦合;观察者⾃⼰决定是否订阅通知,⽬标对象并不关注谁订阅了;观察者不要依赖通知顺序,⽬标对象也不知道通知顺序;常使⽤在基于事件的ui框架中,也是MVC的组成部分;常使⽤在分布式系统中,actor框架中;

  • 本质

    触发联动;

  • 结构图

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/664876.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号