phpではじめるオブジェクト指向(公開用)
DESCRIPTION
TRANSCRIPT
PHPではじめるオブジェクト指向
VOYAGE GROUP田中 康一
自己紹介田中康一
株式会社 VOYAGE GROUP
子会社のFlesselでケータイサイト開発・運用
PHP歴11年
Twitter: @mugeso
アジェンダ自己紹介
アジェンダ
オブジェクト指向とは
PHPでのオブジェクト指向
オブジェクト指向の原則・法則・格言
オブジェクト指向とは
オブジェクトデータを持っている
振る舞いを持っている
メッセージをやり取りする
オブジェクト オブジェクト
オブジェクト
メッセージメッセージ
Web開発現場だと
ディレクター PM
プログラマ
開発依頼
実装依頼
デザイナ
デザイン依頼
PHPでのオブジェクト指向
クラス
例えば
社員
山田さん 鈴木さん 佐藤さん
クラス
インスタンス
コード例class Employee{ private $_name; public function __construct($name) { $this->_name = $name; } public function getName() { return $this->_name; }}
$yamada = new Employee(‘山田’);
継承
例えば
社員
ディレクター エンジニア デザイナ
継承元(親クラス)
派生(子クラス)
コード例class Designer extends Employee{ public function design() { // デザイン処理の実装 }}
$designer = new Designer(‘山田’);$designer->getName(); // Employeeで定義$designer->design(); // Designerで定義
インターフェイス
例えば
デザイナディレクターデザイン依頼
この関係をディレクターが求めている事に
注目してみると
例えば
ディレクターデザイン依頼
デザインできる
このように置き換える事ができます。この「デザインできる」がインターフェイスです。
例えば
デザイナ
デザインできる
デザイン会社
実装としてデザイナやデザイン会社があります。
例えば
デザイン会社ディレクターデザイン依頼
ディレクターは「デザインできる」というインターフェイスに基づき
デザイン会社に依頼できます
コード例interface DesignerInterface{ public function design();}
class Designer extends Employee implements DesignerInterface // ⬅デザイナインターフェイスを実装
{ public function design() { // デザイン処理の実装 }}
コード例// interface DesignerInterface// {// public function design();// }
class DesignerCompany extends Company // 継承元は会社クラス implements DesignerInterface // ⬅デザイナインターフェイスを実装
{ public function design() { // デザイン処理の実装 }}
その他機能多重継承
インターフェイス同士の継承
定数定義
トレイト
例えば……現実世界で例えるのは少し難しい
例えば!映画マトリックスでヘリコプターの操縦方法をインストールしたような感じ。
例えばエンジニア デザイナ
エンジニアとデザイナの技術を抜き出して
例えばエンジニア
プログラミング技術
デザイナ
エンジニアとデザイナの技術を抜き出して
例えばエンジニア
プログラミング技術
デザイナ
デザイン技術
エンジニアとデザイナの技術を抜き出して
例えば
ハイパークリエーター
プログラミング法
デザイン法
再利用ができます。
例えば
ハイパークリエーター
フリーランス
継承元が違ってもOK!
コード例(トレイト定義)
trait CodingTrait{ public function coding($design, $repository) { // 実装 }}
コード例(トレイトの利用)
class Engineer extends Employee{ use CodingTrait;}
$engineer = new Engineer(‘加藤’);$engineer->coding($design, $repository);
コード例(トレイト定義)
trait DesignTrait{ public function design($info, $repository) { // 実装 }}
コード例(トレイトの利用)
class HyperCreator{ use CodingTrait, DesignTrait;}
$creator = new HyperCreator(‘北村’);$creator->coding($design, $repository);$creator->design($info, $repository);
もしここでtrait CodingTrait{ public function coding($design, $repository) {/* 略 */} public function design($info, $repository) {/* 略 */}}
trait DesignTrait{ public function design($info, $repository) {/* 略 */}}
もしここでtrait CodingTrait{ public function coding($design, $repository) {/* 略 */} public function design($info, $repository) {/* 略 */}}
trait DesignTrait{ public function design($info, $repository) {/* 略 */}}
メソッド名が被っていたら
別名をつけるclass HyperCreator{ use CodingTrait, DesignTrait { CodingTrait::design insteadof designCode; DesignTrait::design insteadof designUi; }}
$creator = new HyperCreator(‘北村’);$creator->coding($design, $repository);$creator->designCode($info, $repository);$creator->designUi($info, $repository);
その他機能メソッドの可視性の変更
トレイトを組み合わせたトレイト
トレイトのメンバーの抽象化
静的なメンバー
プロパティ
名前空間
部長
人事部
部長
開発部
同じ部長でも仕事が違う区別したい
例えば
コード例<?php //fileA.phpnamespace Personnel;class Boss{}
<?php //fileB.phpnamespace DevelopDepartment;class Boss{}
コード例<?php // fileC.phpuse DevelopmentDepart;$hoge = new Boss(); // これは開発部部長
<?php // fileD.phpuse Personnel;$hoge = new Boss(); // これは人事部部長$foo = new DevelopmentDepart¥Boss();
原則・法則・格言
注意設計・コーディングの際に意識しましょう
必ず守らなければイケナイわけではありません
理由があればこれらを破るのもアリです
デメテルの法則
ディレクター
デザイナ
デザイン会社
ディレクター
デザイナ
デザイン会社
契約関係 指示の流れ
デザイン会社で人事異動発生!!
担当デザイナが交代
ディレクター
デザイナ
デザイン会社
ディレクター
デザイナ
デザイン会社
どっちが楽ですか?
コーディングではメソッドに渡されたオブジェクトとメンバオブジェクトのみにメッセージを送る
1行に->は1つまで
単一責任の原則(SRP)
「クラスを変更する理由は1つ以上存在してはならない」
社員
じつはこいつは大きすぎる
考えられる変更理由社員番号を持たせたい
給与を振り込めるようにしたい
人事評価をできるようにしたい
人事評価の方法を変更したい
社員
人事評価
給与
変更理由を考えるとこのように分割できる
リスコフの置換原則(LSP)
「派生型はその基本型と置換可能でなければならない」
プログラマ人事
社員
西野さん 北野さん
登場人物
西野さん 北野さん
西野さん 北野さん
人事評価なんだけど
西野さん 北野さん
人事評価なんだけど
え?何のことです?
西野さん 北野さん
人事評価なんだけど
え?何のことです?
社員なら分かれよ・・・
西野さん 北野さん
人事評価なんだけど
え?何のことです?
社員なら分かれよ・・・
社員ができる事はプログラマもできるべき!
具体的には基本クラスのメソッドを使えなくする
派生クラスから例外をなげる
これはNG!!!
開放閉鎖の原則
ソフトウェアの構成要素は、拡張に対して開いていて、
修正に対して閉じていなければならない。
うまく出来ている例ブラウザのプラグイン
外付けハードディスク(パソコンのネジをあけなくても使える)
依存関係逆転の原則
「上位のモジュールは下位のモジュールに依存してはならない。どちらのモジュールも『抽象』に依存すべきである。」
「『抽象』は実装の詳細に依存してはならない。実装の詳細が『抽象』に依存すべきである。」
ディレクター
デザイナ
事業責任者
そのものに依存
ディレクター
デザイナ
事業責任者 ディレクションできる
デザインできる
求める能力にだけ依存
インターフェイス分離の原則
「クライアントに、クライアントが利用しないメソッドへの依存を
強制してはならない。」
例えば
契約できる*個人契約する*法人契約する
個人
株式会社
個人は法人契約は知らなくていい
例えば
個人
株式会社
インターフェイスを分離する
個人契約できる
法人契約できる
Tell,Don’t Ask.
例えば(ask)ディレクタ デザイナ
例えば(ask)ディレクタ デザイナ
背景は何色?
例えば(ask)ディレクタ デザイナ
背景は何色?
#348fddです
例えば(ask)ディレクタ デザイナ
背景は何色?
#348fddです
ここは何px?
例えば(tell)ディレクタ デザイナ
例えば(tell)ディレクタ デザイナ
このコンセプトでデザインよろしく。終わったら送って。
例えば(tell)ディレクタ デザイナ
このコンセプトでデザインよろしく。終わったら送って。
できました。こちらです。
後者の方が役割分担ができている。
コーディングではgetter,setterは極力使わない
getter = getHoge
setter = setHoge
参考文献http://php.net/manual/
http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf
http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/oo-principles.html
http://wiki.shos.info/index.php?%A1%DA%A5%AA%A5%D6%A5%B8%A5%A7%A5%AF%A5%C8%BB%D8%B8%FE%A1%DB%A5%AA