この投稿は4年半前の記事です。 情報が古くなっている可能性があるので、その点ご了承ください。
2013 年 6 月 10 日 1,474日前)
4,438文字 (読了時間11分)

SPONSORED LINK

PHPはHypertext PreProcessorの略語ということになっていますが、実はPersonal HomePageの略だったという超ダサい出自を持っています。ただこの出自は伊達ではなく、ホームページ作っているときに便利だなーという機能を集めていったらPHPになったという、「必要は発明の母」を地でいく言語です。

その由来から察するに、「PHP書けるよー」という人の多くは情報処理の高等教育を受けて来たというより、なんらかの事情でホームページを作っていて、それからPHPを書くようになったというケースが多いんではないでしょうか。

メールフォーム作ったとか、WordPress導入したらPHP書くことになったとか、MySQLと組み合せてみたくなったとか、そういうケースです。僕もそんな感じですね。

僕をはじめとして、こうした人の書くPHPコードは、プログラミングの体系的な知識やWebサイト構築の経験が不足した状態ですので、変なコードになります。いわゆる、スパゲッティコードという奴でしょうか。

フォークに絡めたカルボナーラ
フォークに絡めたカルボナーラ (ぱくたそ)

はじめからできる人はいないので、それはそれで構わないのですが、いつまでも自分の書いた糞コードをメンテし続けるのは嫌ですよね。

そうなると当然リファクタリングが必要になるのですが、ある程度膨大な量のコードを書いてしまった後で、さあどうしよう、となるわけです。よくあるのは、特定の処理を任せていたクラスがめちゃくちゃ膨大になってしまって見るのも嫌というパターンですね。

なぜ膨大なクラスが生まれるのか

「オブジェクト指向については理解しています」とか言っちゃうと道端で絡まれる可能性があるので、まあなんとなく「カプセル化とポリモーフィズムと、えっと……」とか答えておけばいいとは思うのですが、オブジェクト指向プログラミングには一連の処理をクラスに分けて処理を分担させていくという作業が含まれます。この作業がけっこう難しいです。

一連の処理は単なるタスクの山ですが、それをオブジェクト指向によって実現するとなると、いきなり名詞と動詞を沢山考えることになります。ここが躓きのもとです。この結果、一回しか使わないようなメソッドを幾つも持ったグローバルオブジェクトが各ページで何度も呼び出されるような事態となります。

<?php
// ↓こんなのがページのあちこちに出てくる
$my_site_creator->list->render('page1');
?>

オブジェクト指向の説明では、抽象的な概念としてのクラスについて書かれていますが、具体的なモノを知らずしていきなり抽象を発見するのは至難の業です。

デザインパターン? MVC?

デザインパターンは抽象的すぎてわからん

さて、オブジェクト指向プログラミングの世界にはデザインパターンという概念があり、いわば型のようなものなんですが、わりと抽象的な概念のため、経験のない人には理解しづらいんですね。自分が作ろうとしている処理がどのパターンにあてはまるのかは、ぱっとわかりません。Do You PHP?でPHPデザパタが無料で公開されているので、試しに見てみてください。

僕の大学時代の同級生が家庭教師の中一の教え子にいきなり英語の五文型を教えようとしてクビになったことがふと思い出されます。

オブジェクト指向における再利用のためのデザインパターン

オブジェクト指向における再利用のためのデザインパターン [書籍]

著者エリック ガンマ, ラルフ ジョンソン, リチャード ヘルム, ジョン ブリシディース

クリエーターErich Gamma, Ralph Johnson, Richard Helm, John Vlissides, 本位田 真一, 吉田 和樹

出版社ソフトバンククリエイティブ

出版日1999-10

商品カテゴリー単行本

ページ数414

ISBN4797311126

Supported by amazon Product Advertising API

MVCは部分的に導入できるかわからん

またMVCについても、「部分的に導入する」とかはあまりなくて、具体的には「CakePHPを採用する」といった具体的なフレームワークの採用になるわけです。そうなるとサイト作り直しになっちゃいますよね。

もっともMVCの概念についていきなり体得するということをやっているジェダイの騎士みたいな人はおそらく少数派で、ほとんどの人は「なんかよくわからんがCakePHPで書いてたらMVCになってた」が正解じゃないでしょうか。それがフレームワーク本来の使い方です。

CakePHP2 実践入門 (WEB+DB PRESS plus)

CakePHP2 実践入門 (WEB+DB PRESS plus) [書籍]

著者安藤 祐介, 岸田 健一郎, 新原 雅司, 市川 快, 渡辺 一宏, 鈴木 則夫

出版社技術評論社

出版日2012 年 9 月 29 日

商品カテゴリー単行本(ソフトカバー)

ページ数416

ISBN4774153249

Supported by amazon Product Advertising API

とにかく、概念的なものはリファクタリングに採用するにはあまりに抽象的過ぎ、かといってフレームワークを採用すると他の部分も作り直しになっちゃうわけです。

そこで、僕が考えたリファクタリング手法「ペルソナ」の出番ですよ。

ペルソナ=仮面

どんな人でも色んな仮面をかぶって生活していると思いますが、このリファクタリング手法は一つの長大なクラスを幾つもの仮面にわけていく作業です。使うのは抽象クラスだけですね。

たとえ話ですが、Meというクラスを仮定してみます。

class Me{
    public $name = '';

    public function work(){
         $this->typing();
         $this->typing();
    }

    private function typing(){
         echo 'qwerty';
    }

    public function sleep(){
        echo 'zzz…';
    }
}

めんどくさいんで全部書きませんが、僕という人間がやるあらゆるメソッドがこのクラスに実装されていると考えてください。この中で働いている僕はビジネスマンとしての僕なので、抽象クラスBusiness_Manというのを作成し、それをMeに継承させます。

abstract class Business_Man{

    public function work(){
         $this->typing();
         $this->typing();
    }

    protected function typing(){
         echo 'qwerty';
    }
}

class Me extends Business_Man{
}

抽象クラスというのは継承専用のクラスです。この手法のメリットはメソッドを分離する段階でMeの動作がほぼ保証されることです。

で、だんだん慣れて来たら、今度はメソッドのアクセシビリティを変更していきます。「よく考えたら、オフィス行くのは仕事のときだけだな」とかですね。


abstract class Business_Man{

    public function work(){
         $this->go_to_office();
         $this->typing();
         $this->typing();
    }

    private function go_to_office(){
         if(!$this->pasmo_is_ok()){
             $this->charge_pasmo();
         }
         $this->take_train();
    }
}

privateメソッドとprotectedメソッドの違いについては実際にクラスを作成して挙動を確認してください。なんか書いてて思ったんですけど、publicメソッドは命令で、privateとprotectedは自主的な振る舞いと考えると上手くいくんでしょうか。

さてさて、こんな感じである程度わけることができたなーと思ったら、さらに別のクラスを作成し…という感じで多段継承していきましょう。PHPは多重継承ができないので、ちょっとこの部分がダサいんですが、メソッドの整理にはとてもよい工程だと思います。

abstract class Human{} // 人間としての私
abstract class Lover extends Human{} // 恋人としての私
abstract class Father extends Lover{} // 父親としての私
abstract class Business_Man extens Father{} // 仕事人としての私
abstract class Me extends Business_Man{} //すべてを併せて私

なお、PHP5.4だったらTraitがあるので、Traitでわけていけばもっといけてるかもなーと感じたりしています。

とにかく、このペルソナ手法の特徴は以下の通り。

  • 長大なクラスの動作を保証したまま動作できるので、既存のサイトにもすぐ適用できる
  • しっかりと整理できてしまえば、デザインパターンの導入やTraitへの切り替えも楽(なはず)
  • 抽象から具象に行くのではなく、すでに書いてしまった具象を抽象化させていくリファクタリング手法である

というわけで、興味をもった方は試してみてください。

なお、ここまで読んで「最初からMVCでやれや」と思う方もいるでしょうが、どうせ同じレベルの人が書いたらコントローラだけが肥大していく結果になるはずなので、書き散らした具象の山を抽象にわけていく過程は一度ぐらい経験した方がよいと思います。

リファクタリングにもっとも必要なものは勇気なので、この手法があなたの背中を一押しするきっかけになれば、と願います。ユニットテストが導入できないぞーとか悩んでいる人はテスト不能な PHP コードをリファクタリングするための戦略とかも読んでみてください。

 

フォローしてください

ここで会ったのもなにかの縁。
高橋文樹.comの最新情報を見逃さないためにもフォローをお願いします。
めったに送らないメルマガもあります。

SPONSORED LINK

この記事について

この記事はが2013 年 6 月 10 日にプログラミングの記事として公開しました。

高橋先生の電子書籍

高橋先生の電子書籍

Amazonで電子書籍も買えます。

好きな言葉

ふう! 伝記作家って、悪魔だな。

— スティーブン・ミルハウザー

高橋先生の処女作

『途中下車』高橋文樹

2001年幻冬舎NET学生文学大賞受賞作です。

Web制作やります

Web制作やります

Web制作のご依頼は株式会社破滅派へ

不定期メルマガ

高橋文樹.comでは、不定期でニュースレターを配信しています。滅多に送らないので是非購読してください。

高橋文樹.comではプライバシーポリシーに準じて登録情報を取り扱います。