/****************************2018.12.07更新**********************************/
观察者模式:定义对象中一对多的依赖关系,当该对象发生变化时,会通知所有依赖对象进行更新变化。
优点:
1.观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
2.观察者模式在观察目标和观察者之间建立一个抽象的耦合。
3.观察者模式支持广播通信。
4.观察者模式符合“开闭原则”的要求。
缺点:
1.如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2.如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3.观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
代码:
observer.h
#pragma once
#include "stdio.h"
#include <iostream>
#include <string>
using namespace std;
class observer
{
public:
observer();
observer(string desc);
~observer();
virtual void display(int value);
private:
string desc;
};
observer.cpp
#include "observer.h"
observer::observer()
{
this->desc = "";
}
observer::observer(string desc)
{
this->desc = desc;
}
observer::~observer()
{
}
void observer::display(int value)
{
cout << this->desc << ", its value is " << value << endl;
}
observable.h
#pragma once
#include "stdio.h"
#include "observer.h"
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class observable
{
public:
observable();
int addObserver(observer* o);
int removeObserver(observer* o);
void notifyObserver();
void update(int value);
~observable();
private:
vector<observer*> observerList;
int value;
};
observable.cpp
#include "observable.h"
#define SUCCESS 0
#define FAIL 1
observable::observable()
{
observerList.clear();
value = 0;
}
observable::~observable()
{
}
int observable::addObserver(observer* o)
{
if (NULL == o)
return FAIL;
observerList.push_back(o);
return SUCCESS;
}
int observable::removeObserver(observer* o)
{
if (NULL == o)
return FAIL;
for (vector<observer*>::iterator temp = observerList.begin(); temp != observerList.end(); temp++)
{
if (o == *temp)
{
observerList.erase(temp);
return SUCCESS;
}
}
return FAIL;
}
void observable::notifyObserver()
{
for (vector<observer*>::iterator temp = observerList.begin(); temp != observerList.end(); temp++)
{
(*temp)->display(value);
}
}
void observable::update(int value)
{
this->value = value;
notifyObserver();
}
test.cpp
#include "observer.h"
#include "observable.h"
#include <iostream>
int main()
{
observable testO;
observer v1("v1"), v2("v2"), v3("v3");
testO.addObserver(&v1);
testO.addObserver(&v2);
testO.addObserver(&v3);
testO.update(10);
testO.removeObserver(&v3);
testO.update(15);
return 0;
}
装饰者模式:动态地将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
优点:
1.装饰者模式可以提供比继承更多的灵活性。
2.可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
3.通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
4.具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
缺点:
1.会产生很多的小对象,增加了系统的复杂性。
2.这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
代码:
工厂模式:
工厂方法模式:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
优点:
1.子类提供挂钩。基类为工厂方法提供缺省实现,子类可以重写新的实现,也可以继承父类的实现。-- 加一层间接性,增加了灵活性。
2.屏蔽产品类。产品类的实现如何变化,调用者都不需要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
3.高层模块只需要知道产品的抽象类,其他的实现类都不需要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。
4.多态性:客户代码可以做到与特定应用无关,适用于任何实体类。
缺点:
需要Creator和相应的子类作为factory method的载体,如果应用模型确实需要creator和子类存在,则很好;否则的话,需要增加一个类层次。
抽象工厂模式:提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
优点:
1.抽象工厂模式隔离了具体类的生产,使得客户并不需要知道什么被创建。
2.当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
3.增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
增加新的产品等级结构很复杂,需要修改抽象工厂和所有的具体工厂类,对“开闭原则”的支持呈现倾斜性。
单例模式:确保一个类只有一个实例,并提供一个全局访问点。
代码:
class singleton
{
public:
static singleton* getInstance();
static pthread_mutex_t mutex;
private:
singleton()
{
pthread_mutex_init(&mutex);
}
static singleton* p;
};
pthread_mutex_t singleton::mutex;
singleton* singleton::p = NULL;
singleton* singleton::getInstance()
{
if (p == NULL)
{
pthread_mutex_lock(&mutex);
if (p == NULL)
p = new singleton();
pthread_mutex_unlock(&mutex);
}
return p;
}
命令模式:将"请求"封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令对象也支持可撤销的操作。
优点:
1.类间解耦;
2.可扩展性;
3.命令模式结合其他模式会更优秀。
缺点:
命令如果多,会非常庞大。