# 介面 ###### tags: `Design Pattern` 介面指的是有統一且標準化的一種規範 下方已電費為例,不同的季節會有不同的收費標準,如果我們個別去寫了他的類別,之後要新增或是修改就會有些麻煩 所以這時候我們可以考慮使用 **介面(interface)** 的方法來做: ```cpp= #include <iostream> #include <memory> class electricity_bill { public: virtual int caul_electricity_bill(int degree) = 0; } class summer : public electricity_bill { public: int caul_electricity_bill(int degree) override { return degree*3; } } class winter : public electricity_bill { public: int caul_electricity_bill(int degree) override { return degree*2; } } int main() { int total_price = 0 ; std::shared_ptr<electricity_bill> ptr = std::make_shared<summer>(); total_price = ptr->caul_electricity_bill(5); //total_price = 15 } ``` 我們定義了一個**電費的類別(electricity_bill)**,其中我們定義了個**純虛函數用來規範了計算的標準(繼承此類別的子類必須要實做純虛函數)**, 可以看到下方**定義了另外兩個類(summer , winter)**,用來計算不同季節的電費價格,在日後如果要新增或修改也會相對的容易。 --- 另個例子是*深入設計模式*這本書上的例子,假如正在開發一個經營公司的模擬器,使用了不同的類別來代表各種專長的員工: ![](https://i.imgur.com/dDhCzRq.png) ```cpp= class Designer { public: void design() { .... } }; class Programmer { public: void coding() { ... } }; class Tester { public: void test() { ... } }; class Company { public: void createSoftware() { d.designer(); p.coding(); t.test(); } private: Designer d; Programmer p; Tester t; }; ``` *上方的做法會使所有的類別都緊密耦合* 從上方們可以歸納出員工會依照各自專長來處理事情,我們可以設計個介面來實現這件事,如下: ![](https://i.imgur.com/JBcGm6Y.png) 通過員工這個介面來分別對處理各自專長的事情,最後由Company當中的createSoftwate()調用 ```cpp= class employee { public: virtual void doWork(){} ; }; class Designer : public employee { public: void doWork() { std::cout << "I'm a Designer\n"; } }; class Programmer : public employee { public: void doWork() { std::cout << "I'm a Programmer\n"; } }; class Tester : public employee { public: void doWork() { std::cout << "I'm a Tester\n"; } }; class Company { // class emplotee; public: void createSofteare() { d.doWork(); p.doWork(); t.doWork(); } private: Designer d; Programmer p; Tester t; }; ``` 但這個作法雖然已經將員工處理的事情整理成一個介面,但實際上Company類別當中的某些部份還是依賴於employee類。要完全的分開可以參考下方作法: ![](https://i.imgur.com/GoNUApc.png) ```cpp= class employee { public: virtual void doWork(){} ; }; class Designer : public employee { public: void doWork() { std::cout << "I'm a Designer\n"; } }; class Programmer : public employee { public: void doWork() { std::cout << "I'm a Programmer\n"; } }; class Tester : public employee { public: void doWork() { std::cout << "I'm a Tester\n"; } }; class Conpany { public: virtual std::shared_ptr<employee> getEmployee() = 0; void createSoftware() { getEmployee()->doWork(); } }; class GameDevConpany : public Conpany { std::shared_ptr<employee> getEmployee() { std::shared_ptr<employee> ptr = std::make_shared<Programmer>(); return ptr; } }; class OutSourceConpany : public Conpany { std::shared_ptr<employee> getEmployee() { std::shared_ptr<employee> ptr = std::make_shared<Designer>(); return ptr; } }; int main() { //1. 我們要創建那中公司? 遊戲開發公司 //後續假設要改成其餘類型的公司,只需要創造對應的類別,並修改下方 GameDevCompany ,其餘架構都不會動到 std::shared_ptr<Conpany> con_ptr = std::make_shared<GameDevConpany>(); //2. 接著我們可以透過公司去開發遊戲 誰去開發呢?也就是programmer con_ptr->createSoftware(); } ```