Mix-In
http://d.hatena.ne.jp/bobchin/20050914
前に、PHPのAggregate関数を使ってMix-Inみたいなことと書いたけど
http://www.programmers-paradise.com/tdiary/?date=20050915#p04
本来は禁じ手かもしれないが、わかっててやれば有効かもしれませんね・・・
作り方は
- モジュールとして呼ばれる側(Foo)は、インスタンスメソッドとして定義する
- モジュールを利用する側(Bar)は、モジュールをスタティックメソッドとしてコールする
ってかんじかな。
問題は
- Fooがインスタンスかして利用できてしまう(コンストラクタで対応すればいいか・・・)
- Barは必ずインスタンスで利用して欲しい
- プロパティを使用する場合は、FooとBarでプロパティ名を合わせておく必要がある。
ってとこでしょうか?
こんなのはどう?
Mixin.php(Mixinモジュールで制限を加えるクラス)
<?php
class Mixin {
function Mixin()
{
die("Mixinするモジュールはインスタンス化できません");
}
function check($vars = array())
{
isset($this)
or die("Mixinモジュールを使用するにはインスタンス化する必要があります");
!is_a($this, __CLASS__) or die("Mixinモジュールは継承できません");
Mixin::check_vars($vars);
}
function check_vars($vars)
{
$vars = (array)$vars;
$real_vars = get_object_vars($this);
foreach ($vars as $var) {
isset($real_vars[$var])
or die(get_class($this)."にプロパティ'{$var}'が存在しません");
}
}
}
?>
SampleModule.php(Mixinモジュール)
<?php
require_once 'Mixin.php';
class SampleModule extends Mixin {
function println()
{
Mixin::check("s");
print $this->s."\n";
}
function println2($var = "s")
{
Mixin::check($var);
print $this->$var."\n";
}
}
?>
Sample.php(ユーザクラス)
<?php
require_once 'SampleModule.php';
class Foo {
var $s;
var $s2;
function setS($s)
{
$this->s = $s;
}
function println()
{
SampleModule::println();
}
function println2()
{
SampleModule::println2("s2");
}
}
$foo = new Foo();
$foo->setS("ほげ!");
$foo->println();
//$foo->println2();
$foo->s2 = "uni";
$foo->println2();
?>