设计模式(Design pattern)
- 在特定
环境中解决某一问题的方案 - 被反复使用、多数人知晓的、经过分类的
代码设计经验的总结 - 可
重用代码, 让代码更容易被他人理解, 保证代码可靠性
设计模式基本原则
SOLID+D, 核心准则就是面向接口编程,定义接口层。
Single(单一职责)
类的职责要单一,对外只提供一种功能。
Open(开闭)
对
扩展开放,对修改关闭。类的改动是通过增加代码进行扩展的,而不是修改源代码
- 使用接口/抽象类,定义系统的接口层,再通过增加具体实现类来进行扩展。
L(里氏替换)
父类出现的地方都可以用他的子类无缝替换
- 在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
Interface(接口隔离)
一个接口应该只提供一种对外功能,不要把所有功能定义在一个接口。
D 迪米特法则 (最少知道原则)
- 一个对象应当对其他对象尽可能少的了解,减少耦合
- 各个模块之间相互调用时,通常会提供一个统一的接口来实现,来减少模块间的耦合
Depend(依赖倒置原则)
面向接口编程, 接口不能依赖具体实现, 实现可以依赖接口。
单例
适用于全局只有一个对象的场景
class singleton
{
protected:
singleton(){}
private:
static singleton* p;
public:
static singleton* instance();
};
singleton* singleton::p = NULL;
singleton* singleton::instance()
{
if (p == NULL)
p = new singleton();
return p;
}
-
多线程问题
- C++对象创建分成
分配内存+构造过程两步。 - 线程1分配好内存后,还没来得急构造和初始化成员变量,就进行线程切换了
- 线程2拿到所有权后,由于内存已经分配了, 就不会执行构造过程了, 这时候对象的属性值是
未知的。
- C++对象创建分成
-
解决办法
- 静态初始化(推荐)
class singleton
{
private:
static singleton* p;
};
singleton* singleton::p = new singleton;
singleton* singleton::initance()
{
return p;
}
因为静态属性在编译时就初始化到全局区了, 所以全局就只有一份了
- 创建对象过程中加锁
工厂模式
通过专门定义一个类负责创建其他类的实例,被创建的实例通常都具有共同的父类。
- 简单工厂: 工厂类是具体实现, 添加新产品需要修改工厂类
- 抽象工厂: 定义工厂接口, 这样添加新产品只要对应创建一个新的工厂实现类
FruitFactory * ff = NULL; // 工厂接口
Fruit *fruit = NULL; // 产品
ff = new BananaFactory();
fruit = ff->getFruit();
// 添加新的工厂实现就可以定义新产品了
ff = new AppleFactory();
fruit = ff->getFruit();
原型模式prototype
- 用来创建对象的拷贝对象。
- 具有与原型一样的数据。
- 浅拷贝
复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
- 深拷贝
会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象
适配器模式adapter
是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
class Current18v
{
void use18vCurrent()
{
cout << "使用18v的交流电" << endl;
}
}
class Current220v
{
void use220vCurrent()
{
cout << "使用220v的交流电" << endl;
}
}
class Adapter : public Current18v
{
Adapter(Current220v *p220v)
{
m_p220v = p220v;
}
void use18vCurrent()
{
cout << "adapter中使用电流" << endl;
m_p220v->use220vCurrent(); // 适配方法中调用原始220V方法
}
}
Current220v *p220v = new Current220v; // 220V
Adapter *padapter = new Adapter(p220v); //Adapter转换接口
padapter->use18vCurrent(); // 转换成18V
模板模式(template)
在抽象类中统一操作步骤,并规定好接口;让子类实现接口。这样可以把各个具体的子类和操作步骤接耦合
class MakeCar
{
virtual void makeHead() = 0;
virtual void makeBody() = 0;
virtual void makeTail() = 0;
void make() // 把一组行为变成一个模板
{
makeHead();
makeBody();
makeTail();
}
};
class MakeBus : public MakeCar
{
void makeHead()
{
cout << "bus 组装 车头" << endl;
}
void makeBody()
{
cout << "bus 组装 车身" << endl;
}
void makeTail()
{
cout << "bus 组装 车尾" << endl;
}
}
class MakeJeep : public MakeCar
{
void makeHead()
{
cout << "Jeep 组装 车头" << endl;
}
void makeBody()
{
cout << "Jeep 组装 车身" << endl;
}
void makeTail()
{
cout << "Jeep 组装 车尾" << endl;
}
}
MakeCar *bus = new MakeBus;
bus->make();
MakeCar *jeep = new MakeJeep;
jeep->make();
责任链
链条式处理事情。工作流程化、消息处理流程化、事物流程化;
class CarHandle
{
virtual void HandleCar() = 0;
CarHandle *setNextHandle(CarHandle *carhandle)
{
this->carhandle = carhandle;
return this->carhandle;
}
};
class CarHandleHead : public CarHandle
{
void HandleCar()
{
cout << "处理车头" << endl;
if (this->carhandle != NULL)
{
carhandle->HandleCar();
}
}
};
class CarHandleBody : public CarHandle
{
void HandleCar()
{
cout << "处理车身" << endl;
if (this->carhandle != NULL)
{
carhandle->HandleCar();
}
}
};
class CarHandleTail : public CarHandle
{
void HandleCar()
{
cout << "处理车尾" << endl;
if (this->carhandle != NULL)
{
carhandle->HandleCar();
}
}
};
CarHandleHead *head = new CarHandleHead;
CarHandleBody *body = new CarHandleBody;
CarHandleTail *tail = new CarHandleTail;
head->setNextHandle(body);
body->setNextHandle(tail);
tail->setNextHandle(NULL);
//处理
head->HandleCar();
策略模式
准备一组算法,并将每一个算法封装起来,使得它们可以互换。
class Strategy
{
virtual void SymEncrypt() = 0;
};
class Des : public Strategy
{
virtual void SymEncrypt()
{
cout << "Des 加密" << endl;
}
};
class AES : public Strategy
{
virtual void SymEncrypt()
{
cout << "AES 加密" << endl;
}
};
class Context
{
Context(Strategy *strategy)
{
p = strategy;
}
void Operator()
{
p->SymEncrypt();
}
private:
Strategy *p;
};
Strategy *strategy = NULL;
Context *ctx = NULL;
strategy = new AES;
ctx = new Context(strategy);
ctx->Operator();
代理模式(Delegate)
- 定义接口,把一系列过程抽象出来, 用来指定代理双方可以做什么,必须做什么。
观察者模式
- 当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。