C++设计模式初探(一)

一、总则
  1. 单一职责原则:每个类只做一件事,确保引起类变化的原因只有一个;
  2. 开闭原则:对扩展开放,对修改关闭。要增加功能,通过增加代码实现,而不是修改原代码;
  3. 里氏代换原则(LSP):抽象类出现的地方,都可以用他子类代替;
  4. 依赖倒转原则:依赖抽象而不是具体
  5. 接口隔离原则:一个接口干一件事;
  6. 合成复用原则:继承会使父类可能影响子类,因此优先用组合;
  7. 迪米特原则(最少知识原则):一个类对象尽可能少的了解其他类,中介
二、开闭原则

考虑这样的场景:
要设计一个计算器类,要实现加法减法运算,经过一段时间开发之后,任务完成;
现在要新增一个乘法运算,若使用传统的开发方法,就需要修改该计算器类的代码,这不符合开闭原则;
可以先定义一个抽象计算器类,再新建加法计算器类继承于他,减法计算器类继承于他,乘法法计算器类继承于他,如果要加其他功能的话,还可以继续新建类继承于他。

#include <iostream>
using namespace std;

//抽象计算器类
class AbstractCaculator
{
public:
    virtual void setOperateNumber(int a, int b) {};
    virtual int getResult()=0;
};

//加法计算机类,只负责加法
class PlusCaculator :public AbstractCaculator
{
public:
    virtual void setOperateNumber(int a, int b) {
        this->ma = a;
        this->mb = b;
    }
    virtual int getResult() {
        return ma + mb;
    }
private:
    int ma;
    int mb;
};

//减法计算机类,只负责减法
class MinCaculator :public AbstractCaculator
{
public:
    virtual void setOperateNumber(int a, int b) {
        this->ma = a;
        this->mb = b;
    }
    virtual int getResult() {
        return ma - mb;
    }
private:
    int ma;
    int mb;
};
//如果要增加其他运算,只需要继续增加子类

int main()
{
    AbstractCaculator* Caculate = new PlusCaculator;
    Caculate->setOperateNumber(10, 20);
    cout << Caculate->getResult() << endl;
    delete Caculate;

    Caculate = new MinCaculator;
    Caculate->setOperateNumber(10, 20);
    cout << Caculate->getResult() << endl;
    delete Caculate;
}
三、迪米特原则

考虑这样的场景:
现在有楼盘A(高质量),楼盘B(低质量),我要买一套高质量的楼盘,这个设计逻辑该如何实现:
传统方法:定义class A,class B,再在函数中挨个创建AB的实例,挨个判断他们的质量;
但这不符合迪米特原则,即我不需要了解他们是怎么样创建、判断的,我只需要一个高质量的楼盘。
根据迪米特原则:先创建一个抽象类楼盘,再创建class A继承于该抽象楼盘,创建class B继承于该抽象楼盘,再创建一个中介类,创建和判断的逻辑由中介完成,中介接收“高质量”或“低质量”,返回楼盘即可。

#include <iostream>
#include<string>
#include<vector>
using namespace std;

//抽象楼盘
class AbstractBuilding
{
public:
    virtual void sale() {};
    virtual string getQuality()=0;
};

//楼盘A 高质量
class BuildingA :public AbstractBuilding
{
public:
    BuildingA(){
        this->mQuality = "高质量";
    }
    virtual void sale() {
        cout << "楼盘A已被售卖!" << mQuality << endl;
    };
    virtual string getQuality() {
        return mQuality;
    };
public:
    string mQuality;
};

//楼盘B 低质量
class BuildingB :public AbstractBuilding
{
public:
    BuildingB() {
        this->mQuality = "低质量";
    }
    virtual void sale() {
        cout << "楼盘B已被售卖!" << mQuality << endl;
    };
    virtual string getQuality() {
        return mQuality;
    };
public:
    string mQuality;
};

//中介类
class MidClass
{
public:
    MidClass()
    {
        //创建每一个楼盘类
        AbstractBuilding* buliding = new BuildingA;
        this->mallBuildings.push_back(buliding);
        
        buliding = new BuildingB;
        this->mallBuildings.push_back(buliding);
    }
    ~MidClass()
    {
        for (vector<AbstractBuilding*>::iterator it = mallBuildings.begin(); it != mallBuildings.end(); it++)
        {
            if (*it != NULL)
                delete *it;
        }
    }
    AbstractBuilding* findMyBuilding(string quality)
    {
        for (vector<AbstractBuilding*>::iterator it = mallBuildings.begin(); it != mallBuildings.end(); it++)
        {
            if ((*it)->getQuality() == quality)
            {
                return *it;
            }
        }
        return NULL;
    }
public:
    vector<AbstractBuilding*> mallBuildings;
};

int main()
{
    //任务:要找一个高质量的楼盘

    //传统方法 判断每一个楼盘类
    AbstractBuilding* buliding = new BuildingA;
    if (buliding->getQuality() == "高质量")
    {
        buliding->sale();
    }
    delete buliding;

    buliding = new BuildingB;
    if (buliding->getQuality() == "高质量")
    {
        buliding->sale();
    }
    delete buliding;
    //中介模式
    MidClass *mediator = new MidClass;
    buliding = mediator->findMyBuilding("高质量");
    buliding->sale();
}
四、合成复用原则

考虑一个问题,在游戏中,要执行 人开车 这个逻辑,需要什么?
需要对象人,对象车,以及一个开车函数。可以通过继承或者组合来实现,优先使用组合,即在一个类里面嵌入另一个类对象

#include <iostream>
using namespace std;

//抽象车
class AbstractCar
{
public:
    virtual void run() {};
};
//宝马
class BwmCar:public AbstractCar
{
public:
    virtual void run() {
        cout << "宝马启动!" << endl;
    };
};

//大众
class DazhongCar :public AbstractCar
{
public:
    virtual void run() {
        cout << "大众启动!" << endl;
    };
};

//抽象人
class AbstractPerson
{
public:
    virtual void setCar(AbstractCar* car) {};
    virtual void douFeng() {};
public:
    AbstractCar* car;
};

//人A
class PersonA :public AbstractPerson
{
public:
    virtual void setCar(AbstractCar* car) {
        this->car = car;
    };
    virtual void douFeng() {
        car->run();
    };
public:
    AbstractCar* car;
};


int main()
{
    AbstractPerson* A = new PersonA;
    A->setCar(new BwmCar);
    A->douFeng();
    A->setCar(new DazhongCar);
    A->douFeng();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值