如果你说你会面向对象思想,却不会设计模式,这简直就是在自欺欺人,当然理解设计模式是一个漫长的过程,在校生是不可能做到的,他更需要实践中的体验和理论的总结相结合,作为菜鸟的我,也准备去学一把设计模式,品味一下高品质代码的威力!
学习设计模式之前先理解几个常用的设计原则:
一.单一职责原则:
一个类应该只有一个引起他变化的原因,这关乎职责的划分
二.里氏代换原则LSP
一个类继承另一个类时,子类就拥有了父类可以继承下来的属性和操作。理论下,此时使用子类型替换父类型,应该不会引起原来使用父类的程序出现错误
实际中,如果子类覆盖了父类的方法,就会导致里氏代换原则的破坏,这样也违反了OCP原则,所以当子类出现这种情况时常用的避免的方式是将父类的方法只声明不定义,或者在子类中不进行重新定义
三.OCP(开闭原则)
对扩展开放,对改变关闭
分清楚变化的部分和不变的部分,对变化的部分预留下可扩展的方式
四.依赖倒置原则
依赖于抽象,不依赖于具体类
这个原则我觉得在设计模式中最能体现出来。
即高层模块并不是调用底层模块的接口,而是声明底层模块的接口,在底层模块实现它。也就是说高层模块不依赖于底层,他依赖于抽象
五.接口隔离原则:
这一原则在设计模式中也体现的很明显,也就是说用户不应该知道过多的接口声明,并且一个接口如果有太多的用户无关的方法,可能会导致接口污染。
六.最少知识原则:
尽可能的松散类之间的耦合
先来个最简单的:单例模式:
注意这里除了构造函数以外,拷贝构造和赋值函数都应该设置为private,这样可以避免用户通过这些方式来破坏单例模式的意义。
#include<iostream>
using namespace std;
class singleton
{
private:
static singleton* instance;
singleton();
public:
static singleton* getinstance();
};
singleton* singleton::instance=NULL;//初始化static成员
singleton* singleton::getinstance()
{
instance=new singleton();
return instance;
}
singleton::singleton()
{
}
int main()
{
singleton* instance1=singleton::getinstance();
singleton* instance2=singleton::getinstance();
if(instance1==instance2)
cout<<"true"<<endl;
else cout<<"false"<<endl;
system("pause");
return 0;
}
如上实现了共享实例的效果,但是在C++中这种编码风格非常的糟糕,因为实例放在了堆里,却无法释放其内存,网上查看到有一种方式是在类里内嵌一个私有类用于析构操作,但是本人认为这并不是一个好的方式,不符合设计模式的设计思想。最佳的办法是设置一个静态的局部变量,让系统实现自动释放:
#include<iostream>
using namespace std;
class singleton
{
private:
singleton();
public:
static singleton& getinstance();
};
singleton& singleton::getinstance()
{
static singleton instance;
return instance;
}
singleton::singleton()
{
}
int main()
{
singleton instance1=singleton::getinstance();
singleton instance2=singleton::getinstance();
if(&instance1==&instance2)
cout<<"true"<<endl;
else cout<<"false"<<endl;
system("pause");
return 0;
}
如上实现是最佳方式,不过没有考虑线程安全。
单一模式的应用场景:即某个类的实例在内存中只有一个。最为广泛的应用场景是系统日志文件,这样有利于全局控制系统信息;windows下的任务管理器和回收站;数据库的连接池,其为了提高数据库的连接和释放效率,也采用单例模式。总之单例模式更多的用于需要同步和共享的实例中。