toda の投稿一覧

toda

システムの規模の肥大化に伴うクラス数増大により、あるクラスにメソッド追加が集中することがあります。基盤となるクラスのメソッドが増大していくものです。
クラスを追加するときに、その関連メソッドを基盤クラス側のメソッドとして追加していくとそのような事態に陥りがちです。いわゆる、Blob(肥満児)アンチパターンですね。

あまり上手くない例えですが、ある会員情報を保存している MemberTable クラスに対して、その会員情報を操作するフォームを表す Form クラスが追加されていることがある (1:N) とします。

その MemberTable に所属している Form の一覧を取得する getForms() メソッドを MemberTable クラスに追加したいわけですが、静的にメソッドを追加した場合、Form クラスが使われない場合は無駄なメソッドが追加されることになります。

Form クラスだけならまだしも、このようなクラスが増えていくと、常に使用されるとは限らないメソッドが MemberTable クラスに追加されていくことになり、MemberTableのコードが無駄に肥大化することになります。また、 Form クラスの修正の影響が MemberTable クラスに及ぶことがありえるため、修正すべき箇所が複数のコードに分散してしまい保守性の観点からも望ましくはありません。

この問題の一つの解決手段として、メソッドを(必要なときに)動的に追加することで、静的に定義されるメソッド数を減らすという方法があります。
Form クラスが読み込まれた時に、 Form クラスのコード側で MemberTable クラスに getForms() メソッドを追加することができれば、MemberTable クラスのソースに手を加える必要はないので、MemberTable の肥大化を防ぐことができますし、 Form クラスの修正を Form クラスのコードに抑えることができます。

具体的な実装例としては、動的に追加するメソッドを無名関数として登録しておき、基盤クラスの __call() マジックメソッドを経由して呼び出すという方法があります。

class MemberTable {
  // 動的に追加されたメソッドの配列
  static private $_methods = array();

  // 動的にメソッドを追加
  static public function addMethod($name, $func) {
    self::$_methods[$name] = $func;
  }

  // 動的に追加されたメソッドの呼び出し
  public function __call($name, $args)
  {
    $func = self::$_methods[$name];

    // 無名関数に $this を bind してから実行
    call_user_func_array($func->bindTo($this, 'MemberTable'), $args);
  }
}

Form クラス側のコードでは、読み込み時に MemberTable::addMethod() でメソッドを追加します。

class Form {
  // 詳細略
}

// MemberTable クラスに getForms() メソッドを追加
MemberTable::addMethod("getForms", function(){
  // 詳細略
  return $forms;
});

Form クラスが読み込まれるときに、MemberTable::addMethod() でメソッドを追加されているので、何も気にせずに getForms() を呼び出すことができます。

$forms = (new MemberTable())->getForms();

ポイントはメソッドの呼び出し時に、bindTo() で無名関数の $this を bind しておくことです。これを忘れると、無名関数内で $this を参照できません。
あと、bindTo() するときにスコープ(第2引数)にクラス名を指定しておく必要があることをお忘れなく。

しかし、bindTo() が使えるのは PHP 5.4 以降であって、公式パッケージが未だに PHP 5.3 である RedHat/CentOS では、無名関数を $this に bind することはできません。

そこで無名関数の呼び出し時に、引数に $this を暗黙的に追加して、無名関数側の引数として受け取るという方法があります。

class MemberTable {
  public function __call($name, $args)
  {
    // 引数の先頭に $this を追加
    array_unshift($args, $this);

    return call_user_func_array(self::$this->_methods[$name], $args);
  }
}

無名関数を登録するときは、最初の引数で $this を受け取るようにします。
クラスのメソッドは $self 経由で呼び出します。

class::addMethod('method', funciton($self, $arg1, $arg2..){
  // 詳細略
  return $forms;

  // メソッドを呼び出すときは $self から呼び出す
  $self->someMethod();
});

これである程度同様のことが実現できます。
もちろん制約もあって、$self は自身の private, protected メソッドを呼び出すことはできません。

早く RedHat/CentOS の公式パッケージが PHP 5.4 ベースになってくれることを期待したいところです。

Tags:

toda

今年の夏は暑さが身にこたえるくらいの猛暑で、半分溶けているtodaです。

さて、JavaScriptのクラスを書いていて、staitc変数(クラス変数)が必要なことがあります。
しかしながら、現在のJavaScriptにはstatic変数という概念がありません。

続きを見る >>>

Tags: , , , ,

toda

PHPでなんちゃってMixinを実現してみる

Posted Date: 2009-10-23 17:53
Author: / No Comments

秋も深くなってきました。秋の夜長いかがお過ごしですか?
今週末はTOEIC試験を控えていますが、何にも勉強はしておりません。とりあえず、自分の英語力がどれだけ低いのかを確認してきたいと思います。こんにちわ。todaです。

最近、まつもとゆきひろさんご著書の「まつもとゆきひろ コードの世界」を拝読しました。rubyの設計・開発を手掛けた方だけあって、言語についての深い知識と考察や歴史が学べて面白かったです。

今回は、その中で気を引いた、”mixin”という多重継承のスマートな使い方をPHPで実現できないかという実験をしてみます。
続きを見る >>>

Tags: , , , , , ,

toda

PHP 5.3を使ってみました。

Posted Date: 2009-09-30 12:15
Author: / No Comments

誰が名付けたのか分からないままに定着してしまった「シルバーウィーク」でしたが、皆様いかがでしたでしょうか。私は結局家でゴロゴロしている間に終わってしまいました。こんにちわ。毎度どうもtodaです。
どうせ来年以降はもう無いでしょうから、名前を付ける必要があったのか甚だ疑問です。

さて、先日PHP 5.3がリリースされました。
2006年11月にリリースされたPHP 5.2からの約3年後のアップデートとなります。

当社でもPHPを活用しておりますので、その更新情報は気になるところです。
今回はそのPHP 5.3をちょっと触ってみて、個人的に注目している新機能をレビューしてみたいと思います。

続きを見る >>>

Tags: , , , , , , , , , ,

toda

samba + LDAPでPDCを作ろう!(その3)

Posted Date: 2009-09-07 18:57
Author: / 2 Comments

夏も終わりにさしかかって、まだ昼間は暑いですけど、そろそろ朝夕は涼しくなってきました。
ずいぶん過ごしやすくなってきた気がします。油断すると風邪をひきそうですが、なんとか元気です。
todaです。こんにちわ。

さて、第3弾です。
繰り返しになりますが、まずは手順をもう一度確認しましょう。

1. PDC、メンバサーバに必要なパッケージをインストールする。
2. PDCのLDAPサーバを設定する。
3. PDC、メンバサーバのUNIXアカウントの解決するために、nss_ldapを設定する。
4. PDC、メンバサーバのsambaを設定する。
5. LDAPサーバににwindowsドメインの情報、アカウント情報を作成する。
6. メンバサーバをwindowsドメインに参加。

今回は後半の4.から6.までの手順を紹介します。
続きを見る >>>

Tags: , , , , , , , , , , , ,

toda

『学びたいこと2009』

Posted Date: 2009-08-06 18:51
Author: / No Comments

最近、伊豆に泊まりがけで旅行してきました。
海なし県である埼玉に住むこと3○年。今だに海を見るとちょっとアガリます。

旅行前日に購入したcybershotが大活躍。林家ペーか? というくらいバシャバシャ撮ってきました。
こんにちわ。todaです。

今日は「学びたいこと2009」というお題が出ましたので、今年前半の結果を反省しつつ、後半の目標を考えてみます。
続きを見る >>>

Tags: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

toda

samba + LDAPでPDCを作ろう!(その2)

Posted Date: 2009-07-24 18:37
Author: / 1 Comment

鬱陶しい梅雨の季節がようやく明けて、夏本番の湿気にさらに鬱陶しい日々を過ごしているtodaです。
こんにちわ。

さて、先月ぶちあげた新企画の第2段です。
今回から、本格的にsamba + LDAP PDCの環境を構築します。
前回の最後に示した手順をおさらいします。

1. PDC、メンバサーバに必要なパッケージをインストールする。
2. PDCのLDAPサーバを設定する。
3. PDC、メンバサーバのUNIXアカウントの解決するために、nss_ldapを設定する。
4. PDC、メンバサーバのsambaを設定する。
5. LDAPサーバににwindowsドメインの情報、アカウント情報を作成する。
6. メンバサーバをwindowsドメインに参加。

今回は前半の3.までの手順を紹介します。
続きを見る >>>

Tags: , , , , , , , , , , ,

toda

【新連載】samba + LDAPでPDCを作ろう!

Posted Date: 2009-06-24 17:31
Author: / No Comments

6月も下旬になって、ようやく、雨の季節になりましたね。
いや、嬉しいわけでもなんでもなく、鬱陶しいだけですが。
こんにちわ。todaです。

今回のネタは自宅ネットワークにwindowsドメインを立ち上げたので、その記録を紹介します。
といっても、ただのPDCではつまらないので、ユーザデータベースを内部形式であるTDBではなく、LDAPにしました。

続きを見る >>>

Tags: , , , , , , , ,