常见设计模式
设计模式概述及常见设计模式
一,设计模式目的
高内聚,低耦合
提高代码的复用性,将变化和稳定隔离开
二,设计模式原则
1,八大原则
- 依赖倒置原则
- 开放封闭原则
- 单一职责原则
- 替换原则
- 接口隔离原则
- 优先使用组合而不是继承
- 封装变化点
- 针对接口编程
2,依赖倒置原则
变化的代码应该依赖稳定的代码,具体的代码应该依赖抽象的代码
3,开放封闭原则
源代码应该做到对扩展开放,对改变封闭
4,单一职责原则
类的职责应该划分清楚,单一且明确
5,替换原则
子类可以替换掉父类的作用
6,接口隔离原则
提供的接口应当简洁完整,避免累赘
7,优先使用组合而不是继承
组合优于继承,更加灵活,耦合度更低
8,封装变化点
将变化隔离,使得一个类的变化不会影响到其他的类
9,针对接口编程
针对接口之间的标准化调用编程
三,单例模式
1,业务场景
当某个类要求保证全局只有一个对象
2,代码实现
//singleton模式(单例模式)
class Singleton{
private:
Singleton();
Singleton(const Singleton& other);
public:
static Singleton* getInstance();
static Singleton* m_instance;
};
Singleton* Singleton::m_instance=nullptr;
//线程非安全版本
Singleton* Singleton::getInstance() {
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//线程安全版本,但锁的代价过高
Singleton* Singleton::getInstance() {
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
return m_instance;
}
//双检查锁,但由于内存读写reorder不安全
Singleton* Singleton::getInstance() {
if(m_instance==nullptr){
Lock lock;
if (m_instance == nullptr) {
m_instance = new Singleton();
}
}
return m_instance;
}
//C++ 11版本之后的跨平台实现 (volatile)
std::atomic<Singleton*> Singleton::m_instance;
std::mutex Singleton::m_mutex;
Singleton* Singleton::getInstance() {
Singleton* tmp = m_instance.load(std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_acquire);//获取内存fence
if (tmp == nullptr) {
std::lock_guard<std::mutex> lock(m_mutex);
tmp = m_instance.load(std::memory_order_relaxed);
if (tmp == nullptr) {
tmp = new Singleton;
std::atomic_thread_fence(std::memory_order_release);//释放内存fence
m_instance.store(tmp, std::memory_order_relaxed);
}
}
return tmp;
}
四,观察者模式
1,业务场景
当一个类发生变化时,其他与之相关联的一系列类也要做出反应,例如qt里的信号和槽
2,代码实现
//observer模式(观察者模式)
class observer{
public:
virtual void response(void) = 0;
virtual ~observer(){};
};
class subject{
public:
vector<observer*>observers;
virtual void add(observer* observer){
observers.push_back(observer);
}
virtual void del(){
observers.erase(observers.begin());
}
virtual void notifyOfAll(void)=0;
virtual ~subject(){};
};
class concreteSubject:public subject{
public:
virtual void notifyOfAll(void){
cout<<"subject 自身状态开始变化"<<endl;
cout<<endl;
for(auto obs:observers){
obs->response();
}
}
};
class observer1: public observer{
public:
virtual void response(void){
cout<<"observer1 is already"<<endl;
}
};
class observer2: public observer{
public:
virtual void response(void){
cout<<"observer2 is already"<<endl;
}
};
五,代理模式
1,业务场景
由于安全,性能,或者分布式等原因考虑的时候,一个类无法直接访问另外一个类,需要间接代理
2,代码实现
//proxy模式(代理模式)
class ISubject{
public:
virtual void process(void)=0;
virtual ~ISubject(){};
};
class subject{
public:
subject(void){
cout<<"subject 访问成功"<<endl;
}
};
class proxySubject:public ISubject{
public:
subject* mSubject;
virtual void process(void){
mSubject = new subject;
}
};
class client{
protected:
ISubject* mSubject;
public:
void process(void){
mSubject = new proxySubject;
mSubject -> process();
}
};
int main(){
client c;
c.process();
return 0;
}
六,策略模式
1,业务场景
当一个类的算法复杂且容易变化时,将算法单独封装和类本身解耦合常用于消除if else语句
2,代码实现
//strategy模式(策略模式)
class TaxStrategy{
public:
virtual double Calculate()=0;
virtual ~TaxStrategy(){}
};
class CNTax : public TaxStrategy{
public:
virtual double Calculate(){
cout<<"这是 CNTax"<<endl;
}
};
class USTax : public TaxStrategy{
public:
virtual double Calculate(){
cout<<"这是 USTax"<<endl;
}
};
class DETax : public TaxStrategy{
public:
virtual double Calculate(){
cout<<"这是 DETax"<<endl;
}
};
class FRTax : public TaxStrategy{
public:
virtual double Calculate(){
cout<<"这是 FRTax"<<endl;
}
};
class SalesOrder{
private:
TaxStrategy* mTaxStrategy;
public:
SalesOrder(TaxStrategy* TaxStrategy):mTaxStrategy(TaxStrategy){
}
~SalesOrder(){
}
void CalculateTax(){
mTaxStrategy->Calculate();
}
};
int main(){
TaxStrategy* strategy = new CNTax;
SalesOrder* salesOreder = new SalesOrder(strategy);
salesOreder -> CalculateTax();
return 0;
}
七,装饰器模式
1,业务场景
当使用继承的产生的子类数量过于多时,就应该考虑更为灵活的组合来为其动态附着功能
2,代码实现
//decorator模式(装饰器模式)
//业务操作
class Stream{
public:
virtual char Read(int number)=0;
virtual void Seek(int position)=0;
virtual void Write(char data)=0;
virtual ~Stream(){}
};
//主体类
class FileStream: public Stream{
public:
virtual char Read(int number){
//读文件流
}
virtual void Seek(int position){
//定位文件流
}
virtual void Write(char data){
//写文件流
}
};
class NetworkStream :public Stream{
public:
virtual char Read(int number){
//读网络流
}
virtual void Seek(int position){
//定位网络流
}
virtual void Write(char data){
//写网络流
}
};
class MemoryStream :public Stream{
public:
virtual char Read(int number){
//读内存流
}
virtual void Seek(int position){
//定位内存流
}
virtual void Write(char data){
//写内存流
}
};
//扩展操作
// 由于两个子类有相同的成员Stream*,所以这个成员要往上提
DecoratorStream: public Stream{
protected:
Stream* stream;//...
DecoratorStream(Stream * stm):stream(stm){
}
};
class CryptoStream: public DecoratorStream {
public:
CryptoStream(Stream* stm):DecoratorStream(stm){
}
virtual char Read(int number){
//额外的加密操作...
stream->Read(number);//读文件流
}
virtual void Seek(int position){
//额外的加密操作...
stream::Seek(position);//定位文件流
//额外的加密操作...
}
virtual void Write(byte data){
//额外的加密操作...
stream::Write(data);//写文件流
//额外的加密操作...
}
};
class BufferedStream : public DecoratorStream{
Stream* stream;//...
public:
BufferedStream(Stream* stm):DecoratorStream(stm){
}
virtual char Read(int number){
//额外的缓存操作...
stream->Read(number);//读文件流
}
virtual void Seek(int position){
//额外的缓存操作...
stream::Seek(position);//定位文件流
//额外的缓存操作...
}
virtual void Write(byte data){
//额外的缓存操作...
stream::Write(data);//写文件流
//额外的缓存操作...
}
};
void Process(){
//运行时装配
Stream* s1=new FileStream();
CryptoStream* s2=new CryptoStream(s1);
BufferedStream* s3=new BufferedStream(s1);
BufferedStream* s4=new BufferedStream(s2);
}
八,工厂模式
1,业务场景
当在一个类中new一个另外的对象会导致对该对象依赖,通过工厂模式绕开new,使其依赖于抽象类
2,代码实现
//factory模式(工厂模式)
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};
//工厂基类
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=0;
virtual ~SplitterFactory(){}
};
//具体类
class BinarySplitter : public ISplitter{
virtual void split(){
}
};
class TxtSplitter: public ISplitter{
virtual void split(){
}
};
class PictureSplitter: public ISplitter{
virtual void split(){
}
};
class VideoSplitter: public ISplitter{
virtual void split(){
}
};
//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new BinarySplitter();
}
};
class TxtSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new TxtSplitter();
}
};
class PictureSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new PictureSplitter();
}
};
class VideoSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new VideoSplitter();
}
};
class MainForm : public Form
{
SplitterFactory* factory;//工厂
public:
MainForm(SplitterFactory* factory){
this->factory=factory;
}
void Button1_Click(){
ISplitter * splitter=
factory->CreateSplitter(); //多态new
splitter->split();
}
};
九,抽象工厂模式
1,业务场景
绕开new进行一系列相互依赖的对象的创建
2,代码实现
//abstractFactory模式(抽象工厂模式)
//数据库访问有关的基类
class IDBConnection{
};
class IDBCommand{
};
class IDataReader{
};
class IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;
};
//支持SQL Server
class SqlConnection: public IDBConnection{
};
class SqlCommand: public IDBCommand{
};
class SqlDataReader: public IDataReader{
};
class SqlDBFactory:public IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;
};
//支持Oracle
class OracleConnection: public IDBConnection{
};
class OracleCommand: public IDBCommand{
};
class OracleDataReader: public IDataReader{
};
class EmployeeDAO{
IDBFactory* dbFactory;
public:
vector<EmployeeDO> GetEmployees(){
IDBConnection* connection =
dbFactory->CreateDBConnection();
connection->ConnectionString("...");
IDBCommand* command =
dbFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection); //关联性
IDBDataReader* reader = command->ExecuteReader(); //关联性
while (reader->Read()){
}
}
};
十,命令模式
1,业务场景
需要对行为进行”记录、撤销、事务“时,行为的请求和实现应该松耦合
2,代码实现
//commmand模式(命令模式)
class Command
{
public:
virtual void execute() = 0;
};
class ConcreteCommand1 : public Command
{
string arg;
public:
ConcreteCommand1(const string & a) : arg(a) {}
void execute() override
{
cout<< "#1 process..."<<arg<<endl;
}
};
class ConcreteCommand2 : public Command
{
string arg;
public:
ConcreteCommand2(const string & a) : arg(a) {}
void execute() override
{
cout<< "#2 process..."<<arg<<endl;
}
};
class MacroCommand : public Command
{
vector<Command*> commands;
public:
void addCommand(Command *c) { commands.push_back(c); }
void execute() override
{
for (auto &c : commands)
{
c->execute();
}
}
};
int main()
{
ConcreteCommand1 command1("Arg ###");
ConcreteCommand2 command2( "Arg $$$");
MacroCommand macro;
macro.addCommand(&command1);
macro.addCommand(&command2);
macro.execute();
}
十一,责任链模式
1,业务场景
一个请求可能被多个对象处理,需要动态的指定接收者
2,代码实现
enum class RequestType
{
REQ_HANDLER1,
REQ_HANDLER2,
REQ_HANDLER3
};
class Reqest
{
string description;
RequestType reqType;
public:
Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
RequestType getReqType() const { return reqType; }
const string& getDescription() const { return description; }
};
class ChainHandler{
ChainHandler *nextChain;
void sendReqestToNextHandler(const Reqest & req)
{
if (nextChain != nullptr)
nextChain->handle(req);
}
protected:
virtual bool canHandleRequest(const Reqest & req) = 0;
virtual void processRequest(const Reqest & req) = 0;
public:
ChainHandler() { nextChain = nullptr; }
void setNextChain(ChainHandler *next) { nextChain = next; }
void handle(const Reqest & req)
{
if (canHandleRequest(req))
processRequest(req);
else
sendReqestToNextHandler(req);
}
};
class Handler1 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER1;
}
void processRequest(const Reqest & req) override
{
cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
}
};
class Handler2 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER2;
}
void processRequest(const Reqest & req) override
{
cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
}
};
class Handler3 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER3;
}
void processRequest(const Reqest & req) override
{
cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
}
};
int main(){
Handler1 h1;
Handler2 h2;
Handler3 h3;
h1.setNextChain(&h2);
h2.setNextChain(&h3);
Reqest req("process task ... ", RequestType::REQ_HANDLER3);
h1.handle(req);
return 0;
}