面对对象中的设计原则:
SRP(Single Responsibility Principle):单一职责原则,就是说一个类只提供一种功能和仅有一个引起它变化的因素。
**OCP(Open Close Principle):开放封闭原则,**就是对一个类来说,对它的内部修改是封闭的,对它的扩展是开放的。
DIP(Dependence Inversion Principle):依赖倒置原则,就是程序依赖于抽象,而不依赖于实现,它的主要目的是为了降低耦合性,它一般通过反射和配置文件来实现的。
**LSP(Liskov Substitution Principle):里氏替换原则,**就是基类出现的地方,通过它的子类也完全可以实现这个功能
**ISP(Interface Segregation Principle):接口隔离原则,**建立单一接口,不要建立庞大臃肿的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不要试图去建立一个很庞大的接口供所有依赖它的类去调用。
CRP(Composite Reuse Principle):合成复用原则,多用组合设计类,少用继承。
一、单例模式
单例模式只允许创建一个活动的对象(实例),提供了对唯一实例的受控访问。
实现原理: 将能够创建对象的函数都设置为private,通过静态成员返回一个实例。
有两种方式,一个是懒汉式,一个是饿汉式。
懒汉式需要考虑加锁,实现代码如下:
#include <iostream>
#include <pthread.h>
using namespace std;
class singleInstance{
public:
static singleInstance* GetsingleInstance(){
if (instance == NULL){
pthread_mutex_t mutex;//mutex mlock; 加锁互斥
pthread_mutex_lock(&mutex);//mlock.lock();
if (instance == NULL){
instance = new singleInstance();
}
pthread_mutex_unlock(&mutex);//mlock.unlock();
}
return instance;
};
~singleInstance(){};
private:// 涉及创建对象的函数都设置为private
singleInstance(){};
singleInstance(const singleInstance& other){};
singleInstance& operator=(const singleInstance& other){ return *this; };
static singleInstance* instance;
};
//懒汉式
singleInstance* singleInstance::instance = nullptr;
int main(){
// 因为没有办法创建对象,就得采用静态成员函数的方法返回静态成员变量
singleInstance *s = singleInstance::GetsingleInstance();
//singleInstance *s1 = new singleInstance(); // 报错
cout << "Hello World";
return 0;
}
饿汉式实现代码:
#include <iostream>
#include <pthread.h>
using namespace std;
class singleInstance{
public:
static singleInstance* GetsingleInstance(){ // 饿汉式,直接创建一个对象,不需要加锁
static singleInstance instance;
return &instance;
};
~singleInstance(){};
private:// 涉及创建对象的函数都设置为private
singleInstance(){};
singleInstance(const singleInstance& other){};
singleInstance& operator=(const singleInstance& other){ return *this; };
};
int main(){
// 因为没有办法创建对象,就得采用静态成员函数的方法返回
singleInstance *s = singleInstance::GetsingleInstance();
//singleInstance *s1 = new singleInstance(); // 报错
cout << "Hello World";
return 0;
}
二、工厂模式
建立一个工厂类,对实现了同一接口的一些类进行实例的创建。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
#include <iostream>
#include <pthread.h>
using namespace std;
//产品类(抽象类,不能实例化)
class Product{
public:
Product(){};
virtual void show()=0; //纯虚函数
};
class productA:public Product{
public:
productA(){};
void show(){ cout << "product A create!" << endl; };
~productA(){};
};
class productB:public Product{
public:
productB(){};
void show(){ cout << "product B create!" << endl; };
~productB(){};
};
class simpleFactory{ // 工厂类
private:
Product* m;
public:
simpleFactory(){};
Product* product(const string str){
if (str == "productA")
m = new productA();
if (str == "productB")
m = new productB();
return m;
};
};
int main(){
simpleFactory obj; // 创建工厂
Product* pro; // 创建产品
pro = obj.product("productA");
pro->show(); // product A create!
pro = obj.product("productB");
pro->show(); // product B create!
delete pro;
return 0;
}
工厂模式为的就是代码解耦,如果我们不采用工厂模式,如果要创建产品A、B,我们通常做法是不是用switch…case语句?那麻烦了,代码耦合程度高,后期添加更多的产品进来,我们不是要添加更多的case吗?这样就太麻烦了,而且不符合设计模式中的开放封闭原则。
为了进一步解耦,在简单工厂的基础上发展出了抽象工厂模式,即连工厂都抽象出来,实现了进一步代码解耦。代码如下:
#include <iostream>
#include <pthread.h>
using namespace std;
//产品类(抽象类,不能实例化)
class Product{
public:
Product(){}
virtual void show()=0; //纯虚函数
};
//产品A
class ProductA:public Product{
public:
ProductA(){}
void show(){ cout<<"product A create!"<<endl; };
};
//产品B
class ProductB:public Product{
public:
ProductB(){}
void show(){ cout<<"product B create!"<<endl; };
};
class Factory{//抽象类
public:
virtual Product* CreateProduct()=0;
};
class FactorA:public Factory{//工厂类A,只生产A产品
public:
Product* CreateProduct(){
Product* _Product = nullptr;
_Product = new ProductA();
return _Product;
}
};
class FactorB:public Factory{//工厂类B,只生产B产品
public:
Product* CreateProduct(){
Product* _Product = nullptr;
_Product = new ProductB();
return _Product;
}
};
int main(){
Product* _Product = nullptr;
auto MyFactoryA = new FactorA();
_Product = MyFactoryA->CreateProduct();// 调用产品A的工厂来生产A产品
_Product->show();
delete _Product;
auto MyFactoryB=new FactorB();
_Product=MyFactoryB->CreateProduct();// 调用产品B的工厂来生产B产品
_Product->show();
delete _Product;
getchar();
return 0;
}
三、观察者模式
作用:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
#include <iostream>
#include <list>
using namespace std;
class Observer{ // 观察者抽象
public:
virtual void Update(int) = 0;
};
class Subject{ // 被观察者抽象
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
};
class ConcreteObserver1:public Observer{ // 第一个观察者
public:
ConcreteObserver1(Subject *pSubject):m_pSubject(pSubject){}
void Update(int value){
cout << "ConcreteObserver1 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteObserver2 : public Observer{ // 第二个观察者
public:
ConcreteObserver2(Subject *pSubject):m_pSubject(pSubject){}
void Update(int value){
cout << "ConcreteObserver2 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteSubject:public Subject{ // 被观察者
public:
void Attach(Observer *pObserver);
void Detach(Observer *pObserver);
void Notify();
void SetState(int state){
m_iState = state;
}
private:
std::list<Observer *> m_ObserverList;
int m_iState;
};
void ConcreteSubject::Attach(Observer *pObserver){ // 添加观察者
m_ObserverList.push_back(pObserver);
}
void ConcreteSubject::Detach(Observer *pObserver){ // 删除观察者
m_ObserverList.remove(pObserver);
}
void ConcreteSubject::Notify(){ // 通知观察者
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end()){
(*it)->Update(m_iState);
++it;
}
}
int main(){
// Create 被观察者
ConcreteSubject *pSubject = new ConcreteSubject();
// Create 观察者
Observer *pObserver1 = new ConcreteObserver1(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject);
// 改变状态
pSubject->SetState(2);
// 注册观察者
pSubject->Attach(pObserver1);
pSubject->Attach(pObserver2);
pSubject->Notify();// 通知观察者
// 删除观察者
pSubject->Detach(pObserver1);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver1;
delete pObserver2;
delete pSubject;
}
输出:
ConcreteObserver1 get the update. New State:2
ConcreteObserver2 get the update. New State:2
ConcreteObserver2 get the update. New State:3
四、适配器模式
将一个类的接口转换成客户希望的另外一个接口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
主要解决在软件系统中,常常要将一些"现存的对象"放到新的环境中,而新环境要求的接口是现对象不能满足的。
#include <iostream>
#include <list>
using namespace std;
//目标抽象类Robot(机器人接口)
class Robot{
public:
virtual void eat() = 0;
virtual void sleep() = 0;
};
//适配者类Douya(Douya类)
class Douya{
public:
void eat(){
cout << "豆芽吃饭" << endl;
}
void sleep(){
cout << "豆芽睡觉" << endl;
}
};
//适配器类DouyaAdapter(DouyaAdapter类)
class DouyaAdapter : public Robot, public Douya{
public:
void eat(){
cout << "机器人模仿:" ;
Douya::eat();
}
void sleep(){
cout << "机器人模仿:" ;
Douya::sleep();
}
};
//客户端测试类Client
int main(void){
Robot *robot = (Robot*)new DouyaAdapter();
robot->eat(); // 机器人模仿:豆芽吃饭
robot->sleep(); // 机器人模仿:豆芽睡觉
delete robot;
return 0;
}
五、装饰器模式
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。
动态地给一个对象添加一些额外的职责。
#include <iostream>
#include <list>
#include <memory>
using namespace std;
//抽象构件类Transform(变形金刚)
class Transform{
public:
virtual void move() = 0;
};
//具体构件类Car
class Car : public Transform{
public:
Car(){
cout << "变形金刚是一辆车!" << endl;
}
void move(){
cout << "在陆地上移动。" << endl;
}
};
//抽象装饰类
class Changer : public Transform{
public:
Changer(shared_ptr<Transform> transform){
this->transform = transform;
}
void move(){
transform->move();
}
private:
shared_ptr<Transform> transform;
};
//具体装饰类Robot
class Robot : public Changer{
public:
Robot(shared_ptr<Transform> transform) : Changer(transform){
cout << "变成机器人!" << endl;
}
void say(){
cout << "说话!" << endl;
}
};
//具体装饰类AirPlane
class Airplane : public Changer{
public:
Airplane(shared_ptr<Transform> transform) : Changer(transform){
cout << "变成飞机!" << endl;
}
void say(){
cout << "在天空飞翔!" << endl;
}
};
//客户端测试
int main(void){
shared_ptr<Transform> camaro = make_shared<Car>();
camaro->move();
cout << "--------------" << endl;
shared_ptr<Robot> bumblebee = make_shared<Robot>(camaro);
bumblebee->move();
bumblebee->say();
return 0;
}