3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ポリモーフィズム(多態性)とは

Posted at

###ポリモーフィズム(多態性)とは

・IT用語辞典

ポリモーフィズムとは、プログラミング言語の持つ性質の一つで、ある関数やメソッドなどが引数や返り値の数やデータ型などの異なる複数の実装を持ち、呼び出し時に使い分けるようにできること。

・プログラマが知るべき97のこと <カーク・ペパーディーン>

プログラミングにおいてポリモーフィズムとは、同じクラスのオブジェクトやメソッドが、複数の形(form)を取り得るということを意味します。

ちょっと何ゆってるかわかんない。。。

とにかく納得して、理解できるように簡単にすると
**「同じ名前のメソッドで、異なる処理を実現すること」**になります。

では同じ名前のメソッドが異なる処理を実現するとは、どのように実装して、どんな時に使うのか?
ユーザーからのリクエストに対して(GETやPOST)処理を切り分ける、レスポンス処理クラスを使って具体例を見てみます。

・GETリクエスト時 -> ViewResponse
・POSTリクエスト時 -> RedirectResponse

これらのレスポンス処理クラスがそれぞれメソッドを実装していて、処理の内容はそれぞれのクラスによって違います。

そして、実際にユーザーからのリクエストに対して処理をするControllerクラスと
Controllerクラスを呼び出すindex.phpがあります。

####ポリモーフィズムを適用しない場合

RedirectResponse.php
class RedirectResponse
{
    public function redirectResponseHandler()
    {
        // POST時にリダイレクトする処理
    }
}
ViewResponse.php
class ViewResponse
{
    public function viewResponseHandler()
    {
        // GET時にHTMLなどをレスポンスボディとして返す処理
    }
}
Controller.php
class Controller
{
    public function post()
    {
        return new RedirectResponse;
    }

    public function get()
    {
        return new ViewResponse;
    }
}
index.php
$controller = new Controller;
$method = $_SERVER['REQUEST_METHOD'];

// HTTPメソッドがPOSTで来た場合、リダイレクト処理を実行
if ($method === 'POST') {
    $response = $controller->post();
    $response->redirectResponseHandler();
// HTTPメソッドがGETで来た場合、レスポンスボディを返す処理を実行
} else if ($method === 'GET') {
    $response = $controller->get();
    $response->viewResponseHandler();
}

この場合、index.phpでHTTPメソッドの種類によって処理を切り分けて、Controllerクラスのメソッドを呼び出し、Controllerクラスではそれぞれレスポンス処理を行うクラスのオブジェクトを返すという処理をしています。
返ってきたオブジェクトを使って$responseはレスポンス処理を行います。


####ポリモーフィズムを適用した場合

RedirectResponse.php
class RedirectResponse
{
    public function ResponseHandler()
    {
        // POST時にリダイレクトする処理
    }
}
ViewResponse.php
class ViewResponse
{
    public function ResponseHandler()
    {
        // GET時にHTMLなどをレスポンスボディとして返す処理
    }
}
Controller.php
class Controller
{
    public function post()
    {
        return new RedirectResponse;
    }

    public function get()
    {
        return new ViewResponse;
    }
}
index.php
$controller = new Controller;
// HTTPメソッドの種類によって呼びだすメソッドを決定する
$response = match($_SERVER['REQUEST_METHOD']) {
    'POST' => $controller->post(),
    'GET'  => $controller->get()
};
$response->ResponseHandler();

変更した点は、レスポンス処理をするクラスのメソッド名をどちらもResponseHandlerにした点と、index.phpでのメソッドの呼び出し方を変更した点です。
Controllerがどちらのクラスオブジェクトを返したとしても、実行するレスポンス処理はResponseHandlerメソッドと決めているので、index.php側で返ってくるオブジェクトの種類を気にする必要が無くなります。


###これの何がメリットなのか?

もし、メソッド名にそれぞれのクラス毎に別名をつけていたとすると、index.phpでは全てのレスポンス処理メソッドの呼び出しを行わないといけない上に、もし他のレスポンス処理クラスが追加されたとなれば、また追加されたメソッドを呼び出す記述を追加しないといけません。

処理は異なるメソッドに同じ名前をつけて実装しておくことで、index.phpではレスポンス処理クラスが追加されても、ResponseHandlerとしておけば何も変更を加える必要は無く、index.phpとController以降の処理を完全に切り分けることができるため変更が安全になり、コードの量も減り、可読性も向上するということです。

3
0
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
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?