SlideShare a Scribd company logo
1 of 59
Download to read offline
copyright(c) 2013 kuwata-lab.com all rights reserved.
PHPとJavaScriptにおける
オブジェクト指向を比較する
makoto kuwata <kwa@kuwata-lab.com>
http://www.kuwata-lab.com/
2013-09-14 (Sat)
PHPカンファレンス2013
【更新履歴】
・2013-09-17: 大幅に加筆修正
copyright(c) 2013 kuwata-lab.com all rights reserved.
本発表について
• PHPでのオブジェクト指向の仕組みを理解する
• JavaScriptでの(同上)
• Class BaseとPrototype Baseの違いを理解する
• オブジェクト指向言語の基礎知識があること
(クラス、インスタンス、メソッド、etc)
• JavaScriptを書いた経験があること
• 独自の解釈が登場!自分で考えて判断を!
【目的】
【前提】
【注意】
copyright(c) 2013 kuwata-lab.com all rights reserved.
オブジェクト指向機能の仕組み
(PHP編)
Internal Mechanism of OOP in PHP
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
オブジェクト指向機能の肝であるメソッド呼び出しの仕組みを説明します。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
変数はポインタであり、インスタンスオブジェクトを参照しています。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
インスタンスオブジェクトには、クラスオブジェクトへの隠しポインタがあります。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
クラスオブジェクトは、メソッド探索テーブルへのポインタを持っています。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
メソッド名をキーにしてメソッド関数を探し、もしあれば実行します。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
もしメソッド名が見つからなければ、親クラスを ります。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
そこでも同じように、メソッド探索テーブルを使ってメソッドを検索します。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
最後にルートクラスでもメソッドが見つからなければ、実行時エラーとなります。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
function () {
.....
}
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
このように、メソッドは呼び出し時に「探索」される点が、関数と決定的に違います。
オブジェクト指向の柔軟性はこれのおかげですが、関数より遅い原因でもあります。
copyright(c) 2013 kuwata-lab.com all rights reserved.
インスタンス変数とインスタンスメソッド
クラス
x: 15
y: 25
メソッド表
m4
m2
m3
Z: 456
function () {
.....
}
インスタンス変数はインスタン
スのもの(共有されない)
インスタンスメソッドは
クラスのもの(共有される)
メソッド関数
インスタンス
x: 10
y: 20
x: 30
y: 40
copyright(c) 2013 kuwata-lab.com all rights reserved.
is-aポインタ
所属するクラスオブジェクトを指す隠しポインタ◆
つまりインスタンスは、「自分が何者かを知っている」
x: 10
インスタンス クラス
変数
y: 20
is-a ポインタは
is-a 関係を表す
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド探索テーブル
メソッドテーブル
m1
m2
m3
function () {
echo "hello";
}
function ($x) {
return $x + 1;
}
クラス
メソッド名 + メソッド関数へのポインタ◆
メソッド名をキーにして、メソッド関数が動的に検索される
(注)
(注)正確には「メソッドシグニチャ」(詳細は省略)
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッドオーバーライドと parent 呼び出し
変数
インスタンス
クラス
クラス
x: 10
y: 20
メソッド表
メソッド表
m4
m2
m3
m3
m1
m2
Z: 123
Z: 456
メソッド関数
function () {
.....
}
function () {
.....
}
同じ名前で別の関数を
登録するのがオーバーライド
自クラスをスキップして
親クラスから探索するのが
parent 呼び出し
メソッド関数
copyright(c) 2013 kuwata-lab.com all rights reserved.
オブジェクト指向機能の仕組み
(JavaScript編)
Internal Mechanism of OOP in JavaScript
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
JavaScript におけるメソッド呼び出しの仕組みを説明します。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
変数はオブジェクトを指しています。そこにプロパティがあるかを調べます。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
指定されたプロパティがなければ、別のオブジェクトをたどります。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
見つかったプロパティが関数であれば、メソッドとして実行できます。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
見つからなければ、さらに別のオブジェクトをたどって、
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
同じようにプロパティを探します。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
最後までたどっても見つからなかれば、(JSでは) undefined が返されます。
copyright(c) 2013 kuwata-lab.com all rights reserved.
メソッド呼び出し
変数
オブジェクト
オブジェクト
オブジェクト
x: 10
y: 20
function () {
.....
}
m2:
Z: 456
関数オブジェクト
function () {
.....
}
m1:
m2:
関数オブジェクト
このように、JavaScriptの動作もPHPとよく似ています。ただし、クラスやメソッド
探索テーブルは存在せず、すべてオブジェクトで済ませているのが特徴です。
copyright(c) 2013 kuwata-lab.com all rights reserved.
__proto__ プロパティ
プロパティが自分にないときに探しに行く先◆
is-a ポインタに相当するが、任意のオブジェクトを自分で指定可能
height: 15
オブジェクト変数 obj
__proto__:
height: 0
オブジェクト
width: 0
__proto__:
width: 30
color: 'red'
obj.color	 ==	 'red'
(注)
(注)IE9 以前では利用不可
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプチェーン
プロパティが見つかるまで __proto__ をたどる◆
最後までたどっても見つからなければ undefined を返す
y: 20
オブジェクト
__proto__:
x: 10
オブジェクト
y: 10
__proto__:
x: 0
オブジェクト
y: 0
__proto__:
z: 0探してるのが
「y」ならこれ
が使われる
「x」ならこれ
が使われる
「z」ならここ
まで探しにくる
copyright(c) 2013 kuwata-lab.com all rights reserved.
コンストラクタ
function	 Foo(x)	 {
	 	 this.x	 =	 x;
}
Foo.prototype.value	 =	 100;
Foo.prototype.hello	 =	 function()	 {	 ...	 };
prototype:
関数オブジェクト
name: 'Foo'
__proto__:
変数 Foo
関数オブ
ジェクト
value: 100
hello:
__proto__:
オブジェクト
__proto__ と .prototype は
別であることに注意
copyright(c) 2013 kuwata-lab.com all rights reserved.
new 演算子
var	 obj	 =	 new	 Foo(123);
obj.hello();
x: 123
オブジェクト
__proto__:
変数 obj
prototype:
関数オブジェクト
name: 'Foo'
__proto__:
変数 Foo
関数オブ
ジェクト
value: 100
hello:
__proto__:
オブジェクト
空オブジェクトを生成、
__proto__ を設定、
コンストラクタを適用
copyright(c) 2013 kuwata-lab.com all rights reserved.
__proto__ と prototype の違いがわかりません!
Foo.__proto__ は、Foo という(関数)オブジェ
クトのためのもの
◆
new で新規作成するオブジェクトには、何も関係しない
Foo.prototype は、new で新規作成するオブジェ
クトのためのもの
◆
Foo 関数自身のプロトタイプチェーンには、何も関係しない
copyright(c) 2013 kuwata-lab.com all rights reserved.
クラスベース (PHP) と
プロトタイプベース (JS)
Class Base v.s. Prototype Base
copyright(c) 2013 kuwata-lab.com all rights reserved.
北の賢者曰く
プロトタイプベースにいくつかの制約を加えたのが
クラスベースである。
つまり、クラスベースはプロトタイプベースのサブ
セットである。
“
”
http://sumim.no-ip.com/wiki/493
(「超約」してるので原文を確認のこと)
by sumim
copyright(c) 2013 kuwata-lab.com all rights reserved.
is-a ポインタ v.s. __proto__ プロパティ
$obj->isa	 =	 new	 Other();	 	 	 //	 できない
is-a ポインタは、プロブラマが変更できない◆
そもそもプログラマには見えない
obj.__proto__	 =	 new	 Other();	 	 	 //	 できる!
__proto__ プロパティは、自由に変更できる◆
任意のオブジェクトを設定できる
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプベース + 制約 = クラスベース
クラスベース (PHP) プロトタイプベース (JS)
探索
ポインタ
ポイント対象
ポインタ先
クラスチェーン プロトタイプチェーン
is-a ポインタ __proto__ プロパティ
クラスオブジェクトのみ 任意のオブジェクト
変更不可 変更可能
制約がない制約がある!
“プロトタイプベースにいくつかの制約を
加えたのがクラスベースである。”
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプベース ⊃ クラスベース
プロトタイプベース
クラスベース
両者は、排他関係ではなく包含関係◆
制約がある分、クラスベースのほうが「狭い」
“クラスベースはプロトタイプベースの
サブセットである。”
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプベースの
応用パターン
Advanced Pattern of Prorotype Base
copyright(c) 2013 kuwata-lab.com all rights reserved.
設定ファイル用オブジェクト
default (共通)
共通する設定を一元管理◆
開発用と本番用は差分だけを管理
development (開発用)
__proto__:
user: "your-name"
production (本番用)
__proto__:
user: "wpadmin"
pass: "bh#un?j9"
__proto__:
host: "localhost"
port: 3306
user: ""
pass: ""
db: "wordpress"
copyright(c) 2013 kuwata-lab.com all rights reserved.
追記型オブジェクト
一度公開したオブジェクトは一切変更しない◆
変更するかわりに、差分だけのオブジェクトを作り (注)、その
__proto__ にもとのオブジェクトを設定。
(注) 値の削除は、undefined で表現する。
__proto__:
color: "red"
version: 3
__proto__:
height: 125
version: 4
__proto__:
width: 55
version: 2
__proto__:
height: 120
width: 50
color: "pink"
version: 1
created: "09/14"
copyright(c) 2013 kuwata-lab.com all rights reserved.
DCI (Data, Context, Interaction), Decorator Pattern
__proto__:
name: "○×社"
addr: "東京"
phone: "03-..."
created: "09/14"
__proto__:
納期問合せ()
発注処理()
発注先 (Role)
__proto__:
納期回答()
受注処理()
受注先 (Role) 取引先 (Player)
インスタンス単位での拡張や追加がとても自然◆
「差分プログラミング」がクラス単位ではなくインスタンス単位に
「受注先」と
して機能する
「取引先」
「受注先」かつ
「発注先」であ
る「取引先」
(あとで詳しくやります…)
copyright(c) 2013 kuwata-lab.com all rights reserved.
よくある誤解
プロトタイプベースは面倒、クラスベースのほ
うが簡単で便利!〔PHP派による誤解〕
◆
制約がない分、プロトタイプベースのほうが自由度は高い。
また、JavaScriptのクラス定義が面倒なのはJavaScriptの文法がクソ
なせいであって、プロトタイプベースのせいではない。
JSにクラス構文が入ったら、プロトタイプベー
スの特徴が失われてしまう!〔JS派による誤解〕
◆
糖衣構文が入っても、見た目が変わるだけで、プロトタイプベース
であることは変わらない。それよりも __proto__ の標準化が遅れて
いることを心配すべき(そのせいで JS はプロトタイプベースの利
点を活かせていない)。
copyright(c) 2013 kuwata-lab.com all rights reserved.
委譲と継承と
プロトタイプチェーン
Delegation, Inheritance, and Prototype Chain
copyright(c) 2013 kuwata-lab.com all rights reserved.
委譲
機能の一部 or 全部を、他のオブジェクトに任せ
ること(丸投げ!)
class	 Foo	 {
	 	 private	 $m1;
	 	 function	 __constructor()	 {
	 	 	 	 $this->other	 =	 new	 OtherObj();
	 	 }
	 	 function	 hello(arg)	 {
	 	 	 	 $this->other->hello(arg);
	 	 }
	 	 .... 丸投げ!
copyright(c) 2013 kuwata-lab.com all rights reserved.
委譲と継承はよく似ている
##	 継承は、メソッド探索を自動で行ってくれる
$this->isa->methodtbl->hello(...);
##	 委譲は、メソッド探索を自力で行っている
$this->other->hello(...);
◆
◆
委譲は、「継承の自力版」と見なせる
言語サポートはないかわりに、複数の移譲先が可能、変更も可能
継承は、「委譲の限定版」と見なせる
移譲先は1つだけで変更も不可だが、言語サポートがあるので便利
(注)独自の見解です
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプチェーン
##	 委譲と同様に、探索先を自分で設定可能
this.__proto__	 =	 new	 Foo();
##	 継承と同様に、自動的に探索してくれる
$this.hello();
$this.__proto__.hello();
$this.__proto__.__proto__.hello();
◆ プロトタイプチェーンは、委譲と継承の間の子
委譲の柔軟性と、継承の利便性を合わせ持つ
(注)独自の見解です
copyright(c) 2013 kuwata-lab.com all rights reserved.
継承では $this が変わらない
	 1:	 class	 Foo	 {
	 2:	 	 	 function	 hello()	 {	 ...	 }
	 3:	 	 	 function	 main()	 {
	 4:	 	 	 	 	 ...;	 $this->hello();	 ...;
	 5:	 	 	 }
	 6:	 }
	 7:	 class	 Bar	 extends	 Foo	 {
	 8:	 	 	 function	 hello()	 {...}	 	 //	 override
	 9:	 	 	 //	 main()	 はそのまま
10:	 }
11:	 $obj	 =	 new	 Bar();
12:	 $obj->main();
$this は Bar オブ
ジェクトのまま!
オーバーライドした
Bar#hello() が最終的に
呼び出される
難しい話なので、分から
なければ読み飛ばして!
copyright(c) 2013 kuwata-lab.com all rights reserved.
委譲では $this が変わる
	 1:	 class	 Foo	 {
	 2:	 	 	 function	 hello()	 {	 ...	 }
	 3:	 	 	 function	 main()	 {
	 4:	 	 	 	 	 ...;	 $this->hello();	 ...;	 }
	 5:	 }
	 6:	 class	 Bar	 extends	 Foo	 {
	 7:	 	 	 function	 hello()	 {	 ...	 }
	 8:	 	 	 function	 main()	 {
	 9:	 	 	 	 	 $this->foo->main();	 }
10:	 }
11:	 $obj	 =	 new	 Bar();
12:	 $obj->foo	 =	 new	 Foo();
13:	 $obj->main();
この $this は
Bar ではない!
せっかく Bar#hello() を
新しく定義したのに
呼び出されない!
(Decorator patternでありがち)
Foo オブジェクト
が $this になる!
難しい話なので、分から
なければ読み飛ばして!
copyright(c) 2013 kuwata-lab.com all rights reserved.
対策: $this を引数として渡す
class	 Foo	 {
	 	 function	 hello()	 {	 ...	 }
	 	 function	 main($_this=null)	 {
	 	 	 	 if	 ($_this	 ===	 null)	 $_this	 =	 $this;
	 	 	 	 ...;	 $_this->hello();	 ...;
	 	 }
}
class	 Bar	 {
	 	 var	 $foo	 =	 new	 Foo();
	 	 function	 hello()	 {	 ...	 }
	 	 function	 main()	 {
	 	 	 	 $this->foo->main($this);	 }	 }
こんな面倒なことを
全メソッドで行うの?
この用意をしてないクラス
は委譲先にできないの?
難しい話なので、分から
なければ読み飛ばして!
copyright(c) 2013 kuwata-lab.com all rights reserved.
プロトタイプチェーンでは this が変わらない
	 1:	 function	 Foo()	 {}
	 2:	 Foo.prototype.hello	 =	 function()	 {...};
	 3:	 Foo.prototype.main	 =	 function()	 {
	 4:	 	 	 ...;	 this.hello();	 ...;
	 5:	 };
	 6:
	 7:	 function	 Bar()	 {}
	 8:	 Bar.prototype.hello	 =	 function()	 {...};
	 9:	 
10:	 var	 obj	 =	 new	 Bar();
11:	 obj.__proto__	 =	 new	 Foo();
12:	 obj.main();
この this は Bar オ
ブジェクトのまま!
委譲と同じことしてるのに、
Bar#hello() が呼ばれる!
(Decorator pattern大勝利の気配!)
copyright(c) 2013 kuwata-lab.com all rights reserved.
比較表
継承
プロトタイプ
チェーン
委譲
言語サポート
利便性
委譲先数
委譲先
$this
あり あり なし
便利 便利 煩雑
1つだけ 1つだけ 複数指定可能
変更不可 変更可 変更可
変わらない 変わらない 変わる
- 継承をより柔軟にしたもの
- 委譲の煩雑さを解消したもの
copyright(c) 2013 kuwata-lab.com all rights reserved.
クラス設計
改善例
An Example to Improve Class Design
copyright(c) 2013 kuwata-lab.com all rights reserved.
間違ったクラス設計例
class	 受注先	 {
	 	 var	 $name;
	 	 var	 $addr;
	 	 function	 納期回答();
}
class	 発注先	 {
	 	 var	 $name;
	 	 var	 $addr;
	 	 function	 納期問合わせ();
}
「受注先かつ発注先」なら両方に登録が必要◆
実体は同じなのに一元管理されないため、名寄せが必要
自称DB設計上級者に
ありがちな間違い
copyright(c) 2013 kuwata-lab.com all rights reserved.
間違ったクラス設計例
class	 取引先	 {
	 	 var	 $name;
	 	 var	 $addr;
}
class	 受注先	 extends	 取引先	 {
	 	 function	 納期回答();
}
class	 発注先	 extends	 取引先	 {
	 	 function	 納期問合わせ();
}
class	 受発注先	 extends	 受注先,発注先	 {	 }
「受注先が発注先にJob Change!」を表せない◆
一度作ったオブジェクトのクラスは変更できないせい
自称Java上級者に
ありがちな間違い
ダイヤモンド継承!
copyright(c) 2013 kuwata-lab.com all rights reserved.
好ましいクラス設計例
class	 取引先	 {	 	 //	 Player
	 	 var	 $name;
	 	 var	 $addr;
	 	 var	 $受注先	 =	 new	 受注先();
	 	 var	 $発注先	 =	 new	 発注先();
}
class	 受注先	 {	 	 //	 Role
	 	 function	 納期回答();	 }
class	 発注先	 {	 	 //	 Role
	 	 function	 納期問合わせ();	 }
「Player」と「Role」とを分け、委譲を使う◆
「受注先かつ発注先」も「Job Change!」も自然に表現可能
でも、受注先や発注
先って、対応する取
引先オブジェクトが
必要だよね?
copyright(c) 2013 kuwata-lab.com all rights reserved.
より好ましいクラス設計例
class	 取引先	 {	 ...	 }
class	 Role	 {
	 	 var	 $player;
	 	 function	 __constructor($player)	 {
	 	 	 	 $this->player	 =	 $player;
	 	 }
}
class	 受注先	 extends	 Role	 {	 ...	 }
class	 発注先	 extends	 Role	 {	 ...	 }
「Role」が「Player」を保持する(さっきと逆)◆
Role には Player が必要だが、Player には Role は必須ではない
Role が Player を保持
(なぜなら Role には Player が必要だから)
copyright(c) 2013 kuwata-lab.com all rights reserved.
若干の問題点
//	 受注先である取引先
$player	 =	 new	 取引先('○ 商会');
$role	 	 	 =	 new	 受注先($player);
//	 受注先として扱う
echo	 $role->納期回答();
//	 取引先として扱う
echo	 $role->player->name;
echo	 $player->name;
Role と Player で使い方に差がある◆
Player の属性やメソッドに Role からアクセスするとき
Role からは、Player の属性へ
直接にはアクセスできない
copyright(c) 2013 kuwata-lab.com all rights reserved.
そこでプロトタイプベース!
class	 取引先	 {	 ...	 }
class	 Role	 {
	 	 function	 __constructor($player)	 {
	 	 	 	 $this->player	 =	 $player;
	 	 	 	 $this->__proto__	 =	 $player;
	 	 }
}
class	 受注先	 extends	 Role	 {	 ...	 }
class	 発注先	 extends	 Role	 {	 ...	 }
Role をあたかも Player のように扱える◆
Decorator Pattern も DCI もいらんかったんや!
仮に PHP でこれが
可能だとすると…
copyright(c) 2013 kuwata-lab.com all rights reserved.
そこでプロトタイプベース!
//	 受注先	 (Role)	 の役割をもった取引先	 (Player)	 は、
$player	 =	 new	 取引先('○ 商会');
$role	 	 	 =	 new	 受注先($player);
//	 Role	 としても	 Player	 としても扱える
echo	 $role->納期回答();
echo	 $role->name;
//	 複数の	 Role	 を重ねることさえ可能
$role	 =	 new	 発注先($role);	 	 //	 受注先兼発注先
Role をあたかも Player のように扱える◆
Decorator Pattern も DCI もいらんかったんや!
Role なのに、まるで
Player のように扱える!
Any Questions?
おしまい

More Related Content

What's hot

POO en C++
POO en C++POO en C++
POO en C++elharraj
 
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...Hamza SAID
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数Shinichi Kozake
 
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...joaomatosf_
 
漢のPort forwarding
漢のPort forwarding漢のPort forwarding
漢のPort forwardingMinoru Nakata
 
Laravelとテストについて
LaravelとテストについてLaravelとテストについて
LaravelとテストについてTakeo Noda
 
Black Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized CommunicationBlack Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized Communicationmsaindane
 
Document Object Model ( DOM)
Document Object Model ( DOM)Document Object Model ( DOM)
Document Object Model ( DOM)Abdelouahed Abdou
 
Présentation de RMI Java
Présentation de RMI JavaPrésentation de RMI Java
Présentation de RMI JavaZakaria Bouazza
 
アロー演算子とスコープ定義演算子
アロー演算子とスコープ定義演算子アロー演算子とスコープ定義演算子
アロー演算子とスコープ定義演算子iPride Co., Ltd.
 
PHPで並列処理する ライブラリを作った
PHPで並列処理する ライブラリを作ったPHPで並列処理する ライブラリを作った
PHPで並列処理する ライブラリを作ったHironobu Saitoh
 
フロントエンドの技術を刷新した話し。
フロントエンドの技術を刷新した話し。フロントエンドの技術を刷新した話し。
フロントエンドの技術を刷新した話し。Yutaka Horikawa
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesOziel Moreira Neto
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021Natan Silnitsky
 
40分濃縮 PHP classの教室
40分濃縮 PHP classの教室40分濃縮 PHP classの教室
40分濃縮 PHP classの教室Yusuke Ando
 
凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Publicbonjin6770 Kurosawa
 

What's hot (20)

POO en C++
POO en C++POO en C++
POO en C++
 
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...
09 visual basic .net - modules de classes-constructeurs, encapsulation, herit...
 
REALM
REALMREALM
REALM
 
C#とJavaの違い
C#とJavaの違いC#とJavaの違い
C#とJavaの違い
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...
An Overview of Deserialization Vulnerabilities in the Java Virtual Machine (J...
 
MVVM入門
MVVM入門MVVM入門
MVVM入門
 
漢のPort forwarding
漢のPort forwarding漢のPort forwarding
漢のPort forwarding
 
Php cours
Php coursPhp cours
Php cours
 
Laravelとテストについて
LaravelとテストについてLaravelとテストについて
Laravelとテストについて
 
Black Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized CommunicationBlack Hat EU 2010 - Attacking Java Serialized Communication
Black Hat EU 2010 - Attacking Java Serialized Communication
 
Document Object Model ( DOM)
Document Object Model ( DOM)Document Object Model ( DOM)
Document Object Model ( DOM)
 
Présentation de RMI Java
Présentation de RMI JavaPrésentation de RMI Java
Présentation de RMI Java
 
アロー演算子とスコープ定義演算子
アロー演算子とスコープ定義演算子アロー演算子とスコープ定義演算子
アロー演算子とスコープ定義演算子
 
PHPで並列処理する ライブラリを作った
PHPで並列処理する ライブラリを作ったPHPで並列処理する ライブラリを作った
PHPで並列処理する ライブラリを作った
 
フロントエンドの技術を刷新した話し。
フロントエンドの技術を刷新した話し。フロントエンドの技術を刷新した話し。
フロントエンドの技術を刷新した話し。
 
Linguagem de Programação Java para Iniciantes
Linguagem de Programação Java para IniciantesLinguagem de Programação Java para Iniciantes
Linguagem de Programação Java para Iniciantes
 
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
How to successfully manage a ZIO fiber’s lifecycle - Functional Scala 2021
 
40分濃縮 PHP classの教室
40分濃縮 PHP classの教室40分濃縮 PHP classの教室
40分濃縮 PHP classの教室
 
凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public凡人の凡人による凡人のためのデザインパターン第一幕 Public
凡人の凡人による凡人のためのデザインパターン第一幕 Public
 

Viewers also liked

ドラえもんの世界をオブジェクト指向で
ドラえもんの世界をオブジェクト指向でドラえもんの世界をオブジェクト指向で
ドラえもんの世界をオブジェクト指向でyaju88
 
Webエンジニアのサバイバル英会話
Webエンジニアのサバイバル英会話Webエンジニアのサバイバル英会話
Webエンジニアのサバイバル英会話Jumpei iwamura
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from insidejulien pauli
 
9_C言語入門 - 条件分岐について(switch case)
9_C言語入門 - 条件分岐について(switch case)9_C言語入門 - 条件分岐について(switch case)
9_C言語入門 - 条件分岐について(switch case)bc_rikko
 
関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)tadaaki hayashi
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発慎一 古賀
 
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!Yuji Nojima
 

Viewers also liked (11)

ドラえもんの世界をオブジェクト指向で
ドラえもんの世界をオブジェクト指向でドラえもんの世界をオブジェクト指向で
ドラえもんの世界をオブジェクト指向で
 
Webエンジニアのサバイバル英会話
Webエンジニアのサバイバル英会話Webエンジニアのサバイバル英会話
Webエンジニアのサバイバル英会話
 
C#の書き方
C#の書き方C#の書き方
C#の書き方
 
Quick tour of PHP from inside
Quick tour of PHP from insideQuick tour of PHP from inside
Quick tour of PHP from inside
 
9_C言語入門 - 条件分岐について(switch case)
9_C言語入門 - 条件分岐について(switch case)9_C言語入門 - 条件分岐について(switch case)
9_C言語入門 - 条件分岐について(switch case)
 
UXデザイナー1年生の1年間
UXデザイナー1年生の1年間UXデザイナー1年生の1年間
UXデザイナー1年生の1年間
 
関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)関数型言語とオブジェクト指向言語(序章)
関数型言語とオブジェクト指向言語(序章)
 
Unityで覚えるC#
Unityで覚えるC#Unityで覚えるC#
Unityで覚えるC#
 
UX / UIデザインって何?
UX / UIデザインって何?UX / UIデザインって何?
UX / UIデザインって何?
 
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
ちゃんとした C# プログラムを書けるようになる実践的な方法~ Visual Studio を使った 高品質・低コスト・保守性の高い開発
 
最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!最強オブジェクト指向言語 JavaScript 再入門!
最強オブジェクト指向言語 JavaScript 再入門!
 

Similar to PHPとJavaScriptにおけるオブジェクト指向を比較する

G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)Nobuhiro Sue
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会Yuji Otani
 
Prototypeベース in JavaScript
Prototypeベース in JavaScriptPrototypeベース in JavaScript
Prototypeベース in JavaScriptRyo Maruyama
 
WordPress テーマ作成&PHP超入門
WordPress テーマ作成&PHP超入門WordPress テーマ作成&PHP超入門
WordPress テーマ作成&PHP超入門Michinari Odajima
 
Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向1000 VICKY
 
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクトアシアル株式会社
 
Phjosh(仮)プロジェクト
Phjosh(仮)プロジェクトPhjosh(仮)プロジェクト
Phjosh(仮)プロジェクトMoriyoshi Koizumi
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_QueryHidekazu Ishikawa
 
Javascript勉強会資料1
Javascript勉強会資料1Javascript勉強会資料1
Javascript勉強会資料1Kenji Kaneko
 
クライアントサイドjavascript簡単紹介
クライアントサイドjavascript簡単紹介クライアントサイドjavascript簡単紹介
クライアントサイドjavascript簡単紹介しくみ製作所
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造Taku Miyakawa
 
最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)Rui Hirokawa
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to ObjectsYoshifumi Kawai
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?kwatch
 
第5回勉強会
第5回勉強会第5回勉強会
第5回勉強会Mugen Fujii
 

Similar to PHPとJavaScriptにおけるオブジェクト指向を比較する (20)

G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)G*workshop sendai 20100424(v2)
G*workshop sendai 20100424(v2)
 
PHP基礎勉強会
PHP基礎勉強会PHP基礎勉強会
PHP基礎勉強会
 
Prototypeベース in JavaScript
Prototypeベース in JavaScriptPrototypeベース in JavaScript
Prototypeベース in JavaScript
 
WordPress テーマ作成&PHP超入門
WordPress テーマ作成&PHP超入門WordPress テーマ作成&PHP超入門
WordPress テーマ作成&PHP超入門
 
Javascripでオブジェクト指向
Javascripでオブジェクト指向Javascripでオブジェクト指向
Javascripでオブジェクト指向
 
PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5PHPコアから読み解くPHP5.5
PHPコアから読み解くPHP5.5
 
Datomic&datalog紹介
Datomic&datalog紹介Datomic&datalog紹介
Datomic&datalog紹介
 
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト
【アシアル塾】PHPオブジェクト指向再入門・第一回クラスとオブジェクト
 
Lithium Labo #1
Lithium Labo #1Lithium Labo #1
Lithium Labo #1
 
Spock's world
Spock's worldSpock's world
Spock's world
 
ATN No.2 Scala事始め
ATN No.2 Scala事始めATN No.2 Scala事始め
ATN No.2 Scala事始め
 
Phjosh(仮)プロジェクト
Phjosh(仮)プロジェクトPhjosh(仮)プロジェクト
Phjosh(仮)プロジェクト
 
脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query脱コピペ!デザイナーにもわかるPHPとWP_Query
脱コピペ!デザイナーにもわかるPHPとWP_Query
 
Javascript勉強会資料1
Javascript勉強会資料1Javascript勉強会資料1
Javascript勉強会資料1
 
クライアントサイドjavascript簡単紹介
クライアントサイドjavascript簡単紹介クライアントサイドjavascript簡単紹介
クライアントサイドjavascript簡単紹介
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造
 
最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)最新PHP事情 (2000年7月22日,PHPカンファレンス)
最新PHP事情 (2000年7月22日,PHPカンファレンス)
 
An Internal of LINQ to Objects
An Internal of LINQ to ObjectsAn Internal of LINQ to Objects
An Internal of LINQ to Objects
 
正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?正規表現リテラルは本当に必要なのか?
正規表現リテラルは本当に必要なのか?
 
第5回勉強会
第5回勉強会第5回勉強会
第5回勉強会
 

More from kwatch

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアルkwatch
 
なんでもID
なんでもIDなんでもID
なんでもIDkwatch
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方kwatch
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方kwatch
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐkwatch
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)kwatch
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!kwatch
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?kwatch
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Pythonkwatch
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策kwatch
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurialkwatch
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -kwatch
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみたkwatch
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"kwatch
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラムkwatch
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンkwatch
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapperkwatch
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -kwatch
 

More from kwatch (20)

How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Migr8.rb チュートリアル
Migr8.rb チュートリアルMigr8.rb チュートリアル
Migr8.rb チュートリアル
 
なんでもID
なんでもIDなんでもID
なんでもID
 
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
Nippondanji氏に怒られても仕方ない、配列型とJSON型の使い方
 
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
【SQLインジェクション対策】徳丸先生に怒られない、動的SQLの安全な組み立て方
 
O/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐO/Rマッパーによるトラブルを未然に防ぐ
O/Rマッパーによるトラブルを未然に防ぐ
 
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
【公開終了】Python4PHPer - PHPユーザのためのPython入門 (Python2.5)
 
DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!DBスキーマもバージョン管理したい!
DBスキーマもバージョン管理したい!
 
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
SQL上級者こそ知って欲しい、なぜO/Rマッパーが重要か?
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
What is wrong on Test::More? / Test::Moreが抱える問題点とその解決策
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
Pretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/MercurialPretty Good Branch Strategy for Git/Mercurial
Pretty Good Branch Strategy for Git/Mercurial
 
Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -Oktest - a new style testing library for Python -
Oktest - a new style testing library for Python -
 
文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた文字列結合のベンチマークをいろんな処理系でやってみた
文字列結合のベンチマークをいろんな処理系でやってみた
 
I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"I have something to say about the buzz word "From Java to Ruby"
I have something to say about the buzz word "From Java to Ruby"
 
Cより速いRubyプログラム
Cより速いRubyプログラムCより速いRubyプログラム
Cより速いRubyプログラム
 
Javaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジンJavaより速いLL用テンプレートエンジン
Javaより速いLL用テンプレートエンジン
 
Underlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R MapperUnderlaying Technology of Modern O/R Mapper
Underlaying Technology of Modern O/R Mapper
 
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
How to Make Ruby CGI Script Faster - CGIを高速化する小手先テクニック -
 

PHPとJavaScriptにおけるオブジェクト指向を比較する

  • 1. copyright(c) 2013 kuwata-lab.com all rights reserved. PHPとJavaScriptにおける オブジェクト指向を比較する makoto kuwata <kwa@kuwata-lab.com> http://www.kuwata-lab.com/ 2013-09-14 (Sat) PHPカンファレンス2013 【更新履歴】 ・2013-09-17: 大幅に加筆修正
  • 2. copyright(c) 2013 kuwata-lab.com all rights reserved. 本発表について • PHPでのオブジェクト指向の仕組みを理解する • JavaScriptでの(同上) • Class BaseとPrototype Baseの違いを理解する • オブジェクト指向言語の基礎知識があること (クラス、インスタンス、メソッド、etc) • JavaScriptを書いた経験があること • 独自の解釈が登場!自分で考えて判断を! 【目的】 【前提】 【注意】
  • 3. copyright(c) 2013 kuwata-lab.com all rights reserved. オブジェクト指向機能の仕組み (PHP編) Internal Mechanism of OOP in PHP
  • 4. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } オブジェクト指向機能の肝であるメソッド呼び出しの仕組みを説明します。
  • 5. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } 変数はポインタであり、インスタンスオブジェクトを参照しています。
  • 6. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } インスタンスオブジェクトには、クラスオブジェクトへの隠しポインタがあります。
  • 7. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } クラスオブジェクトは、メソッド探索テーブルへのポインタを持っています。
  • 8. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } メソッド名をキーにしてメソッド関数を探し、もしあれば実行します。
  • 9. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } もしメソッド名が見つからなければ、親クラスを ります。
  • 10. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } そこでも同じように、メソッド探索テーブルを使ってメソッドを検索します。
  • 11. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } 最後にルートクラスでもメソッドが見つからなければ、実行時エラーとなります。
  • 12. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 function () { ..... } Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } このように、メソッドは呼び出し時に「探索」される点が、関数と決定的に違います。 オブジェクト指向の柔軟性はこれのおかげですが、関数より遅い原因でもあります。
  • 13. copyright(c) 2013 kuwata-lab.com all rights reserved. インスタンス変数とインスタンスメソッド クラス x: 15 y: 25 メソッド表 m4 m2 m3 Z: 456 function () { ..... } インスタンス変数はインスタン スのもの(共有されない) インスタンスメソッドは クラスのもの(共有される) メソッド関数 インスタンス x: 10 y: 20 x: 30 y: 40
  • 14. copyright(c) 2013 kuwata-lab.com all rights reserved. is-aポインタ 所属するクラスオブジェクトを指す隠しポインタ◆ つまりインスタンスは、「自分が何者かを知っている」 x: 10 インスタンス クラス 変数 y: 20 is-a ポインタは is-a 関係を表す
  • 15. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド探索テーブル メソッドテーブル m1 m2 m3 function () { echo "hello"; } function ($x) { return $x + 1; } クラス メソッド名 + メソッド関数へのポインタ◆ メソッド名をキーにして、メソッド関数が動的に検索される (注) (注)正確には「メソッドシグニチャ」(詳細は省略)
  • 16. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッドオーバーライドと parent 呼び出し 変数 インスタンス クラス クラス x: 10 y: 20 メソッド表 メソッド表 m4 m2 m3 m3 m1 m2 Z: 123 Z: 456 メソッド関数 function () { ..... } function () { ..... } 同じ名前で別の関数を 登録するのがオーバーライド 自クラスをスキップして 親クラスから探索するのが parent 呼び出し メソッド関数
  • 17. copyright(c) 2013 kuwata-lab.com all rights reserved. オブジェクト指向機能の仕組み (JavaScript編) Internal Mechanism of OOP in JavaScript
  • 18. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト JavaScript におけるメソッド呼び出しの仕組みを説明します。
  • 19. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 変数はオブジェクトを指しています。そこにプロパティがあるかを調べます。
  • 20. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 指定されたプロパティがなければ、別のオブジェクトをたどります。
  • 21. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 見つかったプロパティが関数であれば、メソッドとして実行できます。
  • 22. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 見つからなければ、さらに別のオブジェクトをたどって、
  • 23. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 同じようにプロパティを探します。
  • 24. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト 最後までたどっても見つからなかれば、(JSでは) undefined が返されます。
  • 25. copyright(c) 2013 kuwata-lab.com all rights reserved. メソッド呼び出し 変数 オブジェクト オブジェクト オブジェクト x: 10 y: 20 function () { ..... } m2: Z: 456 関数オブジェクト function () { ..... } m1: m2: 関数オブジェクト このように、JavaScriptの動作もPHPとよく似ています。ただし、クラスやメソッド 探索テーブルは存在せず、すべてオブジェクトで済ませているのが特徴です。
  • 26. copyright(c) 2013 kuwata-lab.com all rights reserved. __proto__ プロパティ プロパティが自分にないときに探しに行く先◆ is-a ポインタに相当するが、任意のオブジェクトを自分で指定可能 height: 15 オブジェクト変数 obj __proto__: height: 0 オブジェクト width: 0 __proto__: width: 30 color: 'red' obj.color == 'red' (注) (注)IE9 以前では利用不可
  • 27. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプチェーン プロパティが見つかるまで __proto__ をたどる◆ 最後までたどっても見つからなければ undefined を返す y: 20 オブジェクト __proto__: x: 10 オブジェクト y: 10 __proto__: x: 0 オブジェクト y: 0 __proto__: z: 0探してるのが 「y」ならこれ が使われる 「x」ならこれ が使われる 「z」ならここ まで探しにくる
  • 28. copyright(c) 2013 kuwata-lab.com all rights reserved. コンストラクタ function Foo(x) { this.x = x; } Foo.prototype.value = 100; Foo.prototype.hello = function() { ... }; prototype: 関数オブジェクト name: 'Foo' __proto__: 変数 Foo 関数オブ ジェクト value: 100 hello: __proto__: オブジェクト __proto__ と .prototype は 別であることに注意
  • 29. copyright(c) 2013 kuwata-lab.com all rights reserved. new 演算子 var obj = new Foo(123); obj.hello(); x: 123 オブジェクト __proto__: 変数 obj prototype: 関数オブジェクト name: 'Foo' __proto__: 変数 Foo 関数オブ ジェクト value: 100 hello: __proto__: オブジェクト 空オブジェクトを生成、 __proto__ を設定、 コンストラクタを適用
  • 30. copyright(c) 2013 kuwata-lab.com all rights reserved. __proto__ と prototype の違いがわかりません! Foo.__proto__ は、Foo という(関数)オブジェ クトのためのもの ◆ new で新規作成するオブジェクトには、何も関係しない Foo.prototype は、new で新規作成するオブジェ クトのためのもの ◆ Foo 関数自身のプロトタイプチェーンには、何も関係しない
  • 31. copyright(c) 2013 kuwata-lab.com all rights reserved. クラスベース (PHP) と プロトタイプベース (JS) Class Base v.s. Prototype Base
  • 32. copyright(c) 2013 kuwata-lab.com all rights reserved. 北の賢者曰く プロトタイプベースにいくつかの制約を加えたのが クラスベースである。 つまり、クラスベースはプロトタイプベースのサブ セットである。 “ ” http://sumim.no-ip.com/wiki/493 (「超約」してるので原文を確認のこと) by sumim
  • 33. copyright(c) 2013 kuwata-lab.com all rights reserved. is-a ポインタ v.s. __proto__ プロパティ $obj->isa = new Other(); // できない is-a ポインタは、プロブラマが変更できない◆ そもそもプログラマには見えない obj.__proto__ = new Other(); // できる! __proto__ プロパティは、自由に変更できる◆ 任意のオブジェクトを設定できる
  • 34. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプベース + 制約 = クラスベース クラスベース (PHP) プロトタイプベース (JS) 探索 ポインタ ポイント対象 ポインタ先 クラスチェーン プロトタイプチェーン is-a ポインタ __proto__ プロパティ クラスオブジェクトのみ 任意のオブジェクト 変更不可 変更可能 制約がない制約がある! “プロトタイプベースにいくつかの制約を 加えたのがクラスベースである。”
  • 35. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプベース ⊃ クラスベース プロトタイプベース クラスベース 両者は、排他関係ではなく包含関係◆ 制約がある分、クラスベースのほうが「狭い」 “クラスベースはプロトタイプベースの サブセットである。”
  • 36. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプベースの 応用パターン Advanced Pattern of Prorotype Base
  • 37. copyright(c) 2013 kuwata-lab.com all rights reserved. 設定ファイル用オブジェクト default (共通) 共通する設定を一元管理◆ 開発用と本番用は差分だけを管理 development (開発用) __proto__: user: "your-name" production (本番用) __proto__: user: "wpadmin" pass: "bh#un?j9" __proto__: host: "localhost" port: 3306 user: "" pass: "" db: "wordpress"
  • 38. copyright(c) 2013 kuwata-lab.com all rights reserved. 追記型オブジェクト 一度公開したオブジェクトは一切変更しない◆ 変更するかわりに、差分だけのオブジェクトを作り (注)、その __proto__ にもとのオブジェクトを設定。 (注) 値の削除は、undefined で表現する。 __proto__: color: "red" version: 3 __proto__: height: 125 version: 4 __proto__: width: 55 version: 2 __proto__: height: 120 width: 50 color: "pink" version: 1 created: "09/14"
  • 39. copyright(c) 2013 kuwata-lab.com all rights reserved. DCI (Data, Context, Interaction), Decorator Pattern __proto__: name: "○×社" addr: "東京" phone: "03-..." created: "09/14" __proto__: 納期問合せ() 発注処理() 発注先 (Role) __proto__: 納期回答() 受注処理() 受注先 (Role) 取引先 (Player) インスタンス単位での拡張や追加がとても自然◆ 「差分プログラミング」がクラス単位ではなくインスタンス単位に 「受注先」と して機能する 「取引先」 「受注先」かつ 「発注先」であ る「取引先」 (あとで詳しくやります…)
  • 40. copyright(c) 2013 kuwata-lab.com all rights reserved. よくある誤解 プロトタイプベースは面倒、クラスベースのほ うが簡単で便利!〔PHP派による誤解〕 ◆ 制約がない分、プロトタイプベースのほうが自由度は高い。 また、JavaScriptのクラス定義が面倒なのはJavaScriptの文法がクソ なせいであって、プロトタイプベースのせいではない。 JSにクラス構文が入ったら、プロトタイプベー スの特徴が失われてしまう!〔JS派による誤解〕 ◆ 糖衣構文が入っても、見た目が変わるだけで、プロトタイプベース であることは変わらない。それよりも __proto__ の標準化が遅れて いることを心配すべき(そのせいで JS はプロトタイプベースの利 点を活かせていない)。
  • 41. copyright(c) 2013 kuwata-lab.com all rights reserved. 委譲と継承と プロトタイプチェーン Delegation, Inheritance, and Prototype Chain
  • 42. copyright(c) 2013 kuwata-lab.com all rights reserved. 委譲 機能の一部 or 全部を、他のオブジェクトに任せ ること(丸投げ!) class Foo { private $m1; function __constructor() { $this->other = new OtherObj(); } function hello(arg) { $this->other->hello(arg); } .... 丸投げ!
  • 43. copyright(c) 2013 kuwata-lab.com all rights reserved. 委譲と継承はよく似ている ## 継承は、メソッド探索を自動で行ってくれる $this->isa->methodtbl->hello(...); ## 委譲は、メソッド探索を自力で行っている $this->other->hello(...); ◆ ◆ 委譲は、「継承の自力版」と見なせる 言語サポートはないかわりに、複数の移譲先が可能、変更も可能 継承は、「委譲の限定版」と見なせる 移譲先は1つだけで変更も不可だが、言語サポートがあるので便利 (注)独自の見解です
  • 44. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプチェーン ## 委譲と同様に、探索先を自分で設定可能 this.__proto__ = new Foo(); ## 継承と同様に、自動的に探索してくれる $this.hello(); $this.__proto__.hello(); $this.__proto__.__proto__.hello(); ◆ プロトタイプチェーンは、委譲と継承の間の子 委譲の柔軟性と、継承の利便性を合わせ持つ (注)独自の見解です
  • 45. copyright(c) 2013 kuwata-lab.com all rights reserved. 継承では $this が変わらない 1: class Foo { 2: function hello() { ... } 3: function main() { 4: ...; $this->hello(); ...; 5: } 6: } 7: class Bar extends Foo { 8: function hello() {...} // override 9: // main() はそのまま 10: } 11: $obj = new Bar(); 12: $obj->main(); $this は Bar オブ ジェクトのまま! オーバーライドした Bar#hello() が最終的に 呼び出される 難しい話なので、分から なければ読み飛ばして!
  • 46. copyright(c) 2013 kuwata-lab.com all rights reserved. 委譲では $this が変わる 1: class Foo { 2: function hello() { ... } 3: function main() { 4: ...; $this->hello(); ...; } 5: } 6: class Bar extends Foo { 7: function hello() { ... } 8: function main() { 9: $this->foo->main(); } 10: } 11: $obj = new Bar(); 12: $obj->foo = new Foo(); 13: $obj->main(); この $this は Bar ではない! せっかく Bar#hello() を 新しく定義したのに 呼び出されない! (Decorator patternでありがち) Foo オブジェクト が $this になる! 難しい話なので、分から なければ読み飛ばして!
  • 47. copyright(c) 2013 kuwata-lab.com all rights reserved. 対策: $this を引数として渡す class Foo { function hello() { ... } function main($_this=null) { if ($_this === null) $_this = $this; ...; $_this->hello(); ...; } } class Bar { var $foo = new Foo(); function hello() { ... } function main() { $this->foo->main($this); } } こんな面倒なことを 全メソッドで行うの? この用意をしてないクラス は委譲先にできないの? 難しい話なので、分から なければ読み飛ばして!
  • 48. copyright(c) 2013 kuwata-lab.com all rights reserved. プロトタイプチェーンでは this が変わらない 1: function Foo() {} 2: Foo.prototype.hello = function() {...}; 3: Foo.prototype.main = function() { 4: ...; this.hello(); ...; 5: }; 6: 7: function Bar() {} 8: Bar.prototype.hello = function() {...}; 9: 10: var obj = new Bar(); 11: obj.__proto__ = new Foo(); 12: obj.main(); この this は Bar オ ブジェクトのまま! 委譲と同じことしてるのに、 Bar#hello() が呼ばれる! (Decorator pattern大勝利の気配!)
  • 49. copyright(c) 2013 kuwata-lab.com all rights reserved. 比較表 継承 プロトタイプ チェーン 委譲 言語サポート 利便性 委譲先数 委譲先 $this あり あり なし 便利 便利 煩雑 1つだけ 1つだけ 複数指定可能 変更不可 変更可 変更可 変わらない 変わらない 変わる - 継承をより柔軟にしたもの - 委譲の煩雑さを解消したもの
  • 50. copyright(c) 2013 kuwata-lab.com all rights reserved. クラス設計 改善例 An Example to Improve Class Design
  • 51. copyright(c) 2013 kuwata-lab.com all rights reserved. 間違ったクラス設計例 class 受注先 { var $name; var $addr; function 納期回答(); } class 発注先 { var $name; var $addr; function 納期問合わせ(); } 「受注先かつ発注先」なら両方に登録が必要◆ 実体は同じなのに一元管理されないため、名寄せが必要 自称DB設計上級者に ありがちな間違い
  • 52. copyright(c) 2013 kuwata-lab.com all rights reserved. 間違ったクラス設計例 class 取引先 { var $name; var $addr; } class 受注先 extends 取引先 { function 納期回答(); } class 発注先 extends 取引先 { function 納期問合わせ(); } class 受発注先 extends 受注先,発注先 { } 「受注先が発注先にJob Change!」を表せない◆ 一度作ったオブジェクトのクラスは変更できないせい 自称Java上級者に ありがちな間違い ダイヤモンド継承!
  • 53. copyright(c) 2013 kuwata-lab.com all rights reserved. 好ましいクラス設計例 class 取引先 { // Player var $name; var $addr; var $受注先 = new 受注先(); var $発注先 = new 発注先(); } class 受注先 { // Role function 納期回答(); } class 発注先 { // Role function 納期問合わせ(); } 「Player」と「Role」とを分け、委譲を使う◆ 「受注先かつ発注先」も「Job Change!」も自然に表現可能 でも、受注先や発注 先って、対応する取 引先オブジェクトが 必要だよね?
  • 54. copyright(c) 2013 kuwata-lab.com all rights reserved. より好ましいクラス設計例 class 取引先 { ... } class Role { var $player; function __constructor($player) { $this->player = $player; } } class 受注先 extends Role { ... } class 発注先 extends Role { ... } 「Role」が「Player」を保持する(さっきと逆)◆ Role には Player が必要だが、Player には Role は必須ではない Role が Player を保持 (なぜなら Role には Player が必要だから)
  • 55. copyright(c) 2013 kuwata-lab.com all rights reserved. 若干の問題点 // 受注先である取引先 $player = new 取引先('○ 商会'); $role = new 受注先($player); // 受注先として扱う echo $role->納期回答(); // 取引先として扱う echo $role->player->name; echo $player->name; Role と Player で使い方に差がある◆ Player の属性やメソッドに Role からアクセスするとき Role からは、Player の属性へ 直接にはアクセスできない
  • 56. copyright(c) 2013 kuwata-lab.com all rights reserved. そこでプロトタイプベース! class 取引先 { ... } class Role { function __constructor($player) { $this->player = $player; $this->__proto__ = $player; } } class 受注先 extends Role { ... } class 発注先 extends Role { ... } Role をあたかも Player のように扱える◆ Decorator Pattern も DCI もいらんかったんや! 仮に PHP でこれが 可能だとすると…
  • 57. copyright(c) 2013 kuwata-lab.com all rights reserved. そこでプロトタイプベース! // 受注先 (Role) の役割をもった取引先 (Player) は、 $player = new 取引先('○ 商会'); $role = new 受注先($player); // Role としても Player としても扱える echo $role->納期回答(); echo $role->name; // 複数の Role を重ねることさえ可能 $role = new 発注先($role); // 受注先兼発注先 Role をあたかも Player のように扱える◆ Decorator Pattern も DCI もいらんかったんや! Role なのに、まるで Player のように扱える!