# 介面
###### 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)**,用來計算不同季節的電費價格,在日後如果要新增或修改也會相對的容易。
---
另個例子是*深入設計模式*這本書上的例子,假如正在開發一個經營公司的模擬器,使用了不同的類別來代表各種專長的員工:

```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;
};
```
*上方的做法會使所有的類別都緊密耦合*
從上方們可以歸納出員工會依照各自專長來處理事情,我們可以設計個介面來實現這件事,如下:

通過員工這個介面來分別對處理各自專長的事情,最後由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類。要完全的分開可以參考下方作法:

```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();
}
```