---
# System prepended metadata

title: 介面
tags: [Design Pattern]

---

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