参考:
http://blog.csdn.net/column/details/design.html
http://blog.csdn.net/zhengzhb/article/details/7278174
http://blog.csdn.net/column/details/mydesignpattern.html
面象对象间的关系
依赖: 一个对象作为另一个对象方法的方法参数,局部变量等.
关联、聚合和组合 ,即对象包含另外一个对象
泛化,即继承.
设计6大准则
1 单一职责
一个类就完成一个或者一类功能
Liscov里氏替换原则
子类可以扩展父类的功能,但不能改变父类原有的功能
2 面向接口编程
依赖倒置原则的核心思想是面向接口编程
应用层的逻辑不发生改变,改变其依赖的底层组件(接口),从而改变特定功能
某逻辑依赖某个组建(BASE抽象类,接口类,仅有方法).
3 狄米特法则
个对象应该对其他对象保持最少的了解,尽量降低类与类之间的耦合
开闭准则(open-close)
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭
4 接口隔离准则
定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
问题由来:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
解决方案:将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系。也就是采用接口隔离原则
设计模式
为何要设计模式,可扩展性,大型程序构建。
尴尬的是有时引入了设计模式去解决扩展性A,结果A没解决,需要解决的扩展性B没解决,代码反而冗余了,慎用。
1-4属于创建类模式。
5-x属于行为类模式。
单例模式
解决问题: 某些全局功能的类,仅需要一个实体就好。
饿汉模式 开始就生成好
懒汉模式 真正要用的时候才new
//m_instane和getInstance都是static成员
timerRunner* timerRunner::m_instance = NULL;
timerRunner* timerRunner::getInstance(void)
{
if(NULL == m_instance)
{
pthread_mutex_lock(&mutex);
if(NULL == m_instance)
{
m_instance = new timerRunner(128);
}
pthread_mutex_unlock(&mutex);
}
return m_instance;
}
工厂模式
工厂就是类对象的生产器,管理复杂的对象生成,将具体实例化封装起来,所有对象的new由它来做,而不使用具体类去new各自对象。使用时,先new出工厂,工厂再生产出需要的类。
例子:
A 面食
A1 面条
AA1 儿童面条
B1 饺子
C 西餐
牛排
沙拉
简单工厂模式:
面食仅用一个工厂来生产.用choice选择不同面食,增加面食时,需要修改工厂
class Factory {
Mianshi* produceMianshi(int choice) {
if(choice == Miantiao)
if(choice == 饺子)
}
工厂方法模式:
有一个抽象厂,new出不同厂生产不同的面食,需要新的面食就new新的工厂,不修改原来的工厂。
class MianshiFactory {
virtual Mianshi* produceMianshi() = 0;
}
class MiantiaoFactory : pubcic MianshiFactory {
Miantiao* produceMianshi() {
return new Miantiao();};
}
class JiaoziFactory : pubcic MianshiFactory {
Jiaozi* produceMianshi() {
return new Jiaozi();};
}
抽象工厂模式
扩展抽象工厂.不但可以产面,还可以产西餐,就看派生工厂怎么用了
class SyanticFactory {
virtual Mianshi* produceMianshi() = 0;
virtual Mianshi* produceXican() = 0;
}
组合工厂模式
定义新的抽象工厂,比扩展抽象工厂更灵活。增加个西餐抽象厂 ,厂功能自由组合,比如厂既可以生产饺子,又可以生产牛排.有可以只生产一样。
(遵循职责单一,接口隔离原则)
class BestFactory: public MianshiFacotory , public XicanFactory {
...}
封装的含义:做面条要用到水,面,调料,这些new都封装在new Miantiao()里。
Maintiao* produceMaintiao()
{
Shui * s = new Shui();
Mian * m= new Mian();
Liao * l= new Liao();
}
建造者模式
和工厂模式极为类似。
感觉比抽象工厂就多了个Director
原来是new新的工厂,现在Director来接管和管理工厂的new,再封装一层。
4要素:
Product
AbsBuilder
Builder
Director
原型模式
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。其中有一个词很重要,那就是拷贝。可以说,拷贝是原型模式的精髓所在。
原型模式实现,java里关键就是实现Cloneable接口,才能用clone()函数,深拷贝造成的。
java性能也有区别?大的对象来说,clone比直接new一个性能更好。
对于C++来说,赋值本身就是值语义,其实就是拷贝构造函数,需实现深拷贝,没必要写个clone()函数.
Class a;
Class b = a;//b是a 的拷贝,注意深拷贝,也就是创建了新的实例b,java里的clone()函数
中介者模式
A B 相互影响:
A<-------->B
通过中介类隔离影响,解耦
A<----Meditor---->B
Meditor可以更多的ABCDEFG之间的中介
感觉路由器是个很好的例子:
来源N多,出口N多,通过路由程序,选择合适的路径
避免同事类之间的过度耦合。
使用中介者模式可以将对象间一对多的关联转变为一对一的关联,使对象间的关系易于理解和维护。
使用中介者模式可以将对象的行为和协作进行抽象,能够比较灵活的处理对象间的相互作用。
再举个实际例子:
A:数据来源端 AOA(usb) ADB(socket) IOS(usbmuxd-socket) 发送数据给Meditor
Meditor: Cache
B 应用处理端 只从Meditor接收数据各种应用
Cache仅仅是一个数据转发器,并没有绑定AOA到某个具体应用app1,说中介者模式有点牵强
如果应用是AOA数据只能到app1 app1的数据又要发送到IOS,由cacha绑定路径,
AOA--->APP1 -->processing--->APP2--->IOS
这种cache更符合中介模式中的中介者的角色
观察者模式
定义:对象间的一种一对多的关联关系,当一个对象的状态发生改变时,所有依赖于它的对象做出相应的变化.
(观察者,回调发生的对象)对象A监听对象B(被观察者),只要B的状态发生改变,A得到通知(回调).
回调又是通过多态实现。B含有A的基类指针,调用base->upadte()时,实际调用的是A的子类的具体实现…
叫做“发布-订阅者模式”会不会更好理解.
例子:
1 博客更新,订阅者收到.发布-订阅(Publish-Subsrcibe)
2 mqtt 订阅者无数,发布者一发布,订阅者都收的到,中间件肯定维护了一个订阅者的链表。
链表里元素逐个通知。
这样的结构必然有,若设置优先级,还要用到链表数组.
MSG1- SUB1->SUB2->SUB3
MSG2- SUB1->SUB3->