LoginSignup
5
5

More than 5 years have passed since last update.

Interface(妄想記事)

Last updated at Posted at 2016-06-03

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

前章

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

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

↓こんな感じ。

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

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

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

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

↓こんな感じ。

MySqlDatabase.php

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

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

    function addOrders()
    {
        // 実装
    }
}

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

Interfaceの本質

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

で、ここから説明ね。

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

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

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

MySqlDatabase.php
class MySqlDatabase implements Database
{
    function listOrders()
    {
        // 実装
    }

    function addOrders()
    {
        // 実装
    }

    function removeOrders()
    {
        // 実装
    }

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

Controller.php
$db = new MySqlDatabase();

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

三ヵ月後。

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

ってことでこれ作成↓

OracleDatabase.php
class OracleDatabase implements Database
{
    function listOrders()
    {
        // 実装
    }

    function addOrders()
    {
        // 実装
    }

    function removeOrders()
    {
        // 実装
    }

Controller も変更しなくちゃ!

Controller.php

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

$db = new OracleDatabase();

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

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

妄想

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

ちなみに、

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

ってのがいわゆる疎結合ってやつね。

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

だからどうした

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

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

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

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

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

生徒「そうなんだ」

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

生徒「なるほどな」

終章

ってことで妄想終わり。

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

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5