Interface（妄想記事）

コードを眺めてて、これってInterfaceである必要ある？Classでよくない？みたいなことがあったので少しばかり考えてみた。

# 前章
昔プログラミング（PHP）を習い始めたころ、入門書をいくつか見てみると Interface の項目には必ずと言っていいほど、以下のようなことが書かれている。

```text:入門書
複数の異なるクラスに共通の機能を実装するために、その実体を定義することなく指定する仕組みだよー。
```

↓こんな感じ。

```php:Database.php
interface Database
{
    function listOrders();
    function addOrder();
    function removeOrder();
...
}
```

当時の俺「定義しないなら必要ねーじゃねーかよw」

さらにこんな感じの記述も必ずある。

```text:入門書
継承した側のクラスで実装しないとエラーになるよー。
```

↓こんな感じ。

```php:MySqlDatabase.php

// removeOrder がないよー
// ってことでこれエラーね

class MySqlDatabase implements Database
{
    function listOrders()
    {
        // 実装
    }
    
    function addOrders()
    {
        // 実装
    }
}
```

当時の俺「なんでだよ。おせっかいだよｗ」

# Interfaceの本質
Interface というのは何も Class の抽象化のために用意されているものではない。
そんなことしたいだけなら素直に抽象 Class 使用すればいいだけ。

で、ここから説明ね。

まずさっきも使ったこれ。つまりデータベースにアクセスするインターフェースを用意。

```php:Database.php
interface Database
{
    function listOrders();
    function addOrder();
    function removeOrder();
...
}
```

で、実際のデータベースは MySQL かな。じゃあ Databaseインターフェースを継承するクラスを作成しよー。

```php:MySqlDatabase.php
class MySqlDatabase implements Database
{
    function listOrders()
    {
        // 実装
    }
    
    function addOrders()
    {
        // 実装
    }
    
    function removeOrders()
    {
        // 実装
    }
```

よし、これを Controller で使用してみよー。

```php:Controller.php
$db = new MySqlDatabase();

foreach ($db->listOrders() as $order) {
    // 作業
}
```

三ヵ月後。

やっぱデータベースは Oracle にしよーっと。

ってことでこれ作成↓

```php:OracleDatabase.php
class OracleDatabase implements Database
{
    function listOrders()
    {
        // 実装
    }
    
    function addOrders()
    {
        // 実装
    }
    
    function removeOrders()
    {
        // 実装
    }
```

Controller も変更しなくちゃ！

```php:Controller.php

// 変更はこれだけ -> (MySqlDatabase => OracleDatabase)

$db = new OracleDatabase();

foreach ($db->listOrders() as $order) {
    // 作業
}
```

つまり Interface というのは、この場合で言うと、データベースにアクセスする必要はあるけど、それをどのように実行（implement は実行するっていう意味）するかは Controller からは別に知る必要はないじゃんってこと。
Interface はプログラマの好きなように実行してくれてかまわん。しかもコードの修正は超簡単みたいな。

## 妄想
ちなみに interface って日本語で言うと「接点、仲立ち、連絡役」みたいな意味。
プログラムのこの機能に Interface って名づけた人もおそらく英語圏の出身者だと思うけど、おそらく Controller から見て **仲立ちである Interface** に（このケースで言うと）「データベースのアクセスは頼むよ。だけど実際のアクセス方法とビジネスロジック（データベースから取得したデータをゴニョゴニョすること）はこっちで知る必要もないし、知りたくも無いからw」っていう思想で interface っていう名前を付けたのだろうと勝手に妄想した。

ちなみに、
>こっちで知る必要もないし、知りたくも無いからw

ってのがいわゆる[疎結合](http://www.sophia-it.com/content/%E7%96%8E%E7%B5%90%E5%90%88)ってやつね。

疎結合だとそれぞれのコンポーネントの結びつきが弱いから、例えば上の例で言うと、 「Model である MySqlDatabase を修正しても、Controller である Controller.php には抜本的な修正は必要ないよね」って感じ。

## だからどうした

登場人物：
生徒（プログラミングは習い始めて3ヶ月）
先生（現場経験あり）

生徒「いや、けどどのみち上の例で言っても、俺が作成しようと思ってるちょっとした Webアプリってデータベースは MySQL以外使う気ねーし、Interface って使い道が無いんだけど」

先生「そのとおり。どのみち実装者が君だけのその~~ゴミ~~アプリには必要ない」

生徒「じゃあいったいどんなときに役に立つの？」

先生「大勢の人に使ってもらうために公開するフレームワークとかライブラリなんかを記述するときかな。だって大勢の人が使用するんだから、人によっては Oracle や Postgresも使われるだろうから汎用性は大切だよね」

生徒「そうなんだ」

先生「だいたいデータベースの種類によって別の独立したメソッド作ってたんじゃあ、ひとつひとつ説明するのも面倒だよw それなら Interface を使用して呼び出し方は一緒にしてたほうが楽じゃね？それに関連して"継承クラスでは実装を強制する"ってもの、例えば『このデータベースではこのメソッドは無いからなっ』て言われたら、使用している側からしたらカオスじゃん。そこんところは統一しろよみたいな」

生徒「なるほどな」

## 終章
ってことで妄想終わり。

参考：http://php.net/manual/ja/language.oop5.interfaces.php#107364