面向对象设计原则
原则的目的:高内聚,低耦合
1. 单一职责原则
类的职责单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。
2. 开闭原则
对扩展开放,对修改关闭;增加功能是通过增加代码来实现的,而不是去修改源代码。
#include<iostream>
using namespace std;//开闭原则
//对扩展开放,对修改关闭;增加功能是通过增加代码来实现的,而不是去修改源代码//写一个抽象类
class AbstractCaculator
{
public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;
};//加法计算类
class AddCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;}public:int mA;int mB;
};//减法计算器
class SubCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;}public:int mA;int mB;
};//乘法计算器
class MolCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;}public:int mA;int mB;
};//取模计算器 通过增加代码来实现
class MulCaculator :public AbstractCaculator
{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA % mB;}public:int mA;int mB;
};void test01()
{AbstractCaculator* caculator = new AddCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;delete caculator;caculator = new SubCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;
}int main()
{test01();return 0;
}
3. 里氏代换原则
任何抽象类出现的地方都可以用他的实现类进行替换,实际就是虚拟机制,语言级别实现面向对象功能。
4. 依赖倒转原则
依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。
传统方式:
#include<iostream>
using namespace std;//银行工作人员
class BankWorker
{public:void saveService(){cout << "办理存款业务..." << endl;}void payService(){cout << "办理支付业务..." << endl;}void tranferService(){cout << "办理转账业务..." << endl;}
};//中层模块
void doSaveBussiness(BankWorker* worker) {worker->saveService();
}void doPayBussiness(BankWorker* worker) {worker->payService();
}void doTranferBussiness(BankWorker* worker) {worker->tranferService();
}void test04() {BankWorker* worker = new BankWorker;doSaveBussiness(worker); //办理存款业务doPayBussiness(worker); //办理支付业务doTranferBussiness(worker); //办理转账业务
}int main()
{test04();return 0;
}
依赖倒转原则:
#include<iostream>
using namespace std;//银行工作人员
class AbstractWorker
{
public:virtual void doBusiness() = 0;
};//专门办理存款业务的工作人员
class SaveBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理存款业务..." << endl;}
};//专门办理支付业务的工作人员
class PayBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理支付业务..." << endl;}
};//专门办理转账业务的工作人员
class TransferBankWorker :public AbstractWorker
{
public:virtual void doBusiness(){cout << "办理转账业务..." << endl;}
};//中层业务
void doNewBussiness(AbstractWorker* worker)
{worker->doBusiness();
}void test04_1()
{AbstractWorker* transfer = new TransferBankWorker;doNewBussiness(transfer);
}int main()
{test04_1();return 0;
}
5. 接口隔离原则
不应该强迫用户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去。
6. 迪米特法则(最少知识原则)
一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节,这样当一个模块内部的实现发生改变时,不会影响其他模块的使用。(黑盒原理)
#include<iostream>
#include<string>
#include<vector>
using namespace std;//迪米特法则---最少知识原则
class AbstractBuilding
{
public:virtual void sale() = 0;virtual string getQuality() = 0;
};//楼盘A
class BuildingA : public AbstractBuilding
{
public:BuildingA(){m_Quality = "高品质";}virtual void sale(){cout << "楼盘A" << m_Quality << "被售卖!" << endl;}virtual string getQuality(){return m_Quality;}public:string m_Quality;
};//楼盘B
class BuildingB : public AbstractBuilding
{
public:BuildingB(){m_Quality = "低品质";}virtual void sale(){cout << "楼盘B" << m_Quality << "被售卖!" << endl;}virtual string getQuality(){return m_Quality;}
public:string m_Quality;
};//客户端
void test02()
{BuildingA* ba = new BuildingA;if (ba->m_Quality == "高品质"){ba->sale();}BuildingB* bb = new BuildingB;if (bb->m_Quality == "低品质"){bb->sale();}
}//中介类
class Mediator
{
public:Mediator(){AbstractBuilding* building = new BuildingA;vBuilding.push_back(building);building = new BuildingB;vBuilding.push_back(building);}//对外提供接口AbstractBuilding* findMyBuilding(string quality){for (vector<AbstractBuilding*>::iterator it = vBuilding.begin(); it != vBuilding.end(); it++)if ((*it)->getQuality() == quality){return *it;}return NULL;}~Mediator(){for (vector<AbstractBuilding *>::iterator it = vBuilding.begin();it != vBuilding.end();it++)if (*it != NULL){delete* it;}}public:vector<AbstractBuilding *> vBuilding;
};void test02_1()
{Mediator* meidator = new Mediator;AbstractBuilding* building = meidator->findMyBuilding("高品质");if (building != NULL){building->sale();}else{cout << "没有符合条件的楼盘!" << endl;}
}int main()
{test02();test02_1();return 0;
}
7. 合成复用原则
如果使用继承,会导致父类的任何变换都可能影响到子类的行为。
如果使用对象组合,就降低了这种依赖关系。
对于继承和组合,优先使用组合。
#include<iostream>
using namespace std;//抽象车
class AbstructCar
{
public:virtual void run() = 0;
};//大众车
class Dazhong :public AbstructCar
{
public:virtual void run(){cout << "大众车启动" << endl;}
};//拖拉机
class Tuolaji :public AbstructCar
{
public:virtual void run(){cout << "拖拉机启动" << endl;}
};//针对具体类,不适用继承
#if 0
class Person :public Tuolaji
{
public:void Douofeng(){run();}
};class PersonB :public Dazhong
{
public:void Douofeng(){run();}
};
#endif//可以使用组合
class Person
{
public:void setCar(AbstructCar *car){this->car = car;}void Doufeng(){this->car->run();if (this->car != NULL){delete this->car;this->car = NULL;}}public:AbstructCar* car;
};void test03()
{Person* p = new Person;p->setCar(new Dazhong);p->Doufeng();p->setCar(new Tuolaji);p->Doufeng();delete p;
}//继承和组合 优先使用组合
int main()
{test03();return 0;
}