面向對象設計原則
原則的目的:高內聚,低耦合
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;
}