设计模式
转载请注明出处:https://blog.csdn.net/liang19890820/article/details/66974516
重复发明轮子并不是一件有创造性 的事
站在巨人的肩膀上解决问题会更加有效
1. 核心:提供问题的解决方案,更加方便的复用成功的设计和体系结构
2. 基本要素:
2.1 模式名称:描述设计模式的问题、解决方案和效果
2.2 问题:描述在何时使用模式,解释了设计问题和问题存在的前因后果
2.3解决方案:描述设计的组成成分,他们之间的相互关系及各自的职责和协作方式
2.4效果:描述模式应用的效果和使用模式应权衡的问题
3.分类:
3.1 创建型模式(5种):
https://blog.csdn.net/liang19890820/article/details/66974516#%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F
https://blog.csdn.net/tongyuehong137/article/details/45439853
工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
3.2 结构型模式(7种):
https://blog.csdn.net/liang19890820/article/details/66974516#%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F
https://blog.csdn.net/u010097777/article/details/32913347
适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
3.3 行为型模式(11种):
https://blog.csdn.net/liang19890820/article/details/66974516#%E5%88%9B%E5%BB%BA%E5%9E%8B%E6%A8%A1%E5%BC%8F
https://blog.csdn.net/u010097777/article/details/35580347
策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
3.4 剩余两种其他类型(2种):并发型模式和线程池模式(用图片描述)
3.5 设计模式总结:
https://blog.csdn.net/yiyele/article/details/75199965
https://blog.csdn.net/longronglin/article/details/1454315
4.最终目的:高内聚,低耦合
5.设计模式的六大原则:
5.1 总原则:开闭原则
开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类等,后面的具体设计中我们会提到这点。
5.2 单一职责原则:
类的职责要单一,只对外提供一种功能,而引起类变化的原因都应该只有一个,如若不然,就应该把类拆分
5.2 里氏替换原则:
子类对父类的方法尽量不要重写和重载。因为父类代表了定义好的结构,通过这个规范的接口与外界交互,子类不应该随便破坏它,任何抽象类出现的地方都可以用它的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象的功能。
5.3 依赖倒转原则:
依赖于(抽象)接口,不要依赖具体的实现(类),也就是针对接口编程 。写代码时用到具体类时,不与具体类交互,而与具体类的上层接口交互。
#include<iostream>
using namespace std;
class HardDisk{
public:
virtual void work() = 0;
};
class Memory{
public:
virtual void work() = 0;
};
class Cpu{
public:
virtual void work() = 0;
};
class Computer{
private:
HardDisk *m_harddisk;
Memory *m_memory;
Cpu *m_Cpu;
public:
Computer(HardDisk *m_harddisk, Memory *m_memory, Cpu *m_Cpu){
this->m_harddisk = m_harddisk;
this->m_memory = m_memory;
this->m_Cpu = m_Cpu;
}
void work(){
m_harddisk->work();
m_memory->work();
m_Cpu->work();
}
virtual ~Computer(){
delete m_Cpu;
delete m_harddisk;
delete m_memory;
}
};
class InterCpu :public Cpu{
public:
void work(){
cout << "InterCpu work!" << endl;
}
};
class KingStonHardDisk :public HardDisk{
public:
void work(){
cout << "KingStonHardDisk work!" << endl;
}
};
class SanDiskMemory :public Memory{
public:
void work(){
cout << "SanDiskMemory work!" << endl;
}
};
int main(void){
Computer *computer = new Computer(new KingStonHardDisk(), new SanDiskMemory(), new InterCpu());
computer->work();
delete computer;
}
5.4 接口隔离原则:
不应该强迫客户的程序依赖他们不需要的接口方法,一个接口只应该提供一种对外功能,不应该把所有的操作都封装在一个接口中去。每个接口中不存在子类用不到却必须实现的方法,如果不然,就要将接口拆分。使用多个隔离的接口,比使用单个接口(多个接口方法集合到一个的接口)要好。
5.5 迪米特法则(最少知道原则)
就是说:一个类对自己依赖的类知道的越少越好。也就是说无论被依赖的类多么复杂,都应该将逻辑封装在方法的内部,通过public方法提供给外部。这样当被依赖的类变化时,才能最小的影响该类。
最少知道原则的另一个表达方式是:只与直接的朋友通信。类之间只要有耦合关系,就叫朋友关系。耦合分为依赖、关联、聚合、组合等。我们称出现为成员变量、方法参数、方法返回值中的类为直接朋友。局部变量、临时变量则不是直接的朋友。我们要求陌生的类不要作为局部变量出现在类中。
5.6 合成复用原则:(优先使用组合而不是继承原则 )
如果使用继承,会导致父类的任何变换都可能影响到子类的行为。
如果使用对象组合就降低了这种依赖关系。