2008-09-17 12 views

答えて

5

私はLSB次のシナリオについては、この必要:その後、

  • あなたは電子メールサーバーからメッセージをダウンロードする「メールプロセッサ」デーモンを構築している想像し、それを分類し、それを解析し、それを保存し、メッセージの種類に応じて何かを行います。
  • クラス階層:基本メッセージクラスがあり、子 "BouncedMessage"と "AcceptedMessage"があります。
  • それぞれのメッセージタイプには、ディスク上にそれ自身を保持する独自の方法があります。たとえば、BouncedMessageタイプのすべてのメッセージは、BouncedMessage-id.xmlとして自身を保存しようとします。一方、AcceptedMessageは、AcceptedMessage-timestamp.xmlのように、それ自体を別々に保存する必要があります。ここで重要なのは、ファイル名パターンを決定するロジックがサブクラスによって異なりますが、はサブクラス内のすべてのアイテムに対してを共有しています。それが静的な方法であることが理にかなっている理由です。
  • 基本メッセージクラスには、抽象的な静的メソッド(yes、abstract および静的)の「保存」があります。 BouncedMessageは、このメソッドを具体的な静的メソッドで実装します。その後、実際にメッセージを取得し、クラスの内部で、あなたが呼び出すことができます "::(保存)"

あなたは主題についての詳細を知りたい場合:

+1

この場合の* why *を追加することができれば、 '' 'static ::' ''は単純に抽象的な*非static *メソッドを使うよりも簡単になるでしょう。私にとっては、 '' save() ''は、とにかく静的コンテキストから呼び出す理由がないが、おそらく何かが欠けているようだ。 – SeldomNeedy

1

オーバーロードされた静的プロパティ/メソッドにアクセスする必要がある場合サブクラスでオーバーロードされています - あなたは遅い静的バインディングが必要です。簡単な例:あなたはこのようになります。これは、PHPで同様のものを実装しようとした場合paste2.org

は、古典的な例は、RailsのからのActiveRecordクラスです:class User extends ActiveRecord、その後、実際にActiveRecord::find()で呼び出されるUser::find(1)メソッドを呼び出そうあなたはUserfind()をオーバーロードしていないので - しかしActiveRecordfind()方法を結合後半静的ずにそれが(それは常にActiveRecordを指します内self)から呼ばれました分類を知る方法がないので、それがフェッチすることはできませんあなたあなたのためのユーザーオブジェクト。

5

私が遅い静的バインディングを必要とする主なものは、静的インスタンス作成メソッドのセットです。

このDateAndTime classは、私がSmalltalk/SqueakからPHPに移植した年表ライブラリの一部です。静的インスタンス作成メソッドを使用すると、さまざまなタイプの引数タイプを持つインスタンスを作成できます。ただし、静的メソッドでパラメータチェックを行い、ライブラリのコンシューマが完全に有効でないインスタンスを取得できないようにします。

レイトスタティックバインディングは、このような静的インスタンス作成メソッドの実装によって、元々コールによってどのクラスがターゲットにされたかを判断できるようにするために便利です。LSBで

:ここでは使用方法の一例である

class DateAndTime { 

    public static function now() { 
     $class = static::myClass(); 
     $obj = new $class; 
     $obj->setSeconds(time()); 
     return $obj; 
    } 

    public static function yesterday() { 
     $class = static::myClass(); 
     $obj = new $class; 
     $obj->setSeconds(time() - 86400); 
     return $obj; 
    } 

    protected static function myClass() { 
     return 'DateAndTime'; 
    } 
} 

class Timestamp extends DateAndTime { 

    protected static function myClass() { 
     return 'Timestamp'; 
    } 
} 


// Usage: 
$date = DateAndTime::now(); 
$timestamp = Timestamp::now(); 

$date2 = DateAndTime::yesterday(); 
$timestamp2 = Timestamp::yesterday(); 

なしには遅延静的バインディング、[私の現在の実装のように、この例のように、すべてのインスタンスの作成方法を実装する必要があり、各クラス:

numbeとして

class DateAndTime { 

    public static function now($class = 'DateAndTime') { 
     $obj = new $class; 
     $obj->setSeconds(time()); 
     return $obj; 
    } 

    public static function yesterday($class = 'DateAndTime') { 
     $obj = new $class; 
     $obj->setSeconds(time() - 86400); 
     return $obj; 
    } 

} 

class Timestamp extends DateAndTime { 

    public static function now($class = 'Timestamp') { 
     return self::now($class); 
    } 

    public static function yesterday($class = 'Timestamp') { 
     return self::yesterday($class); 
    } 

} 

:LSBなし

インスタンス作成メソッドとクラス階層の増加は、メソッドの複製が突き合わせに本当の痛みになります。 LSBはこの重複を減らし、よりクリーンで簡単な実装を可能にします。

3

それはときに便利です:あなたはクラス階層にわたって変化する機能を持っている

  1. 機能は、あなたが(決定的)階層の上に同じシグネチャを持っており、

  2. 機能をオフにするインスタンスはありません。

#1と#2だけが得られた場合は、通常のインスタンスメソッドを使用します。だからアレックスの問題(この質問に対する彼の答えを参照)はLSBを必要としません。

典型的なケースは、サブクラスが異なる方法で自身を作成するが、同じパラメータを使用するオブジェクト作成です。明らかに呼び出すインスタンスがないので、作成メソッド(ファクトリメソッドとも呼ばれます)は静的でなければなりません。しかし、その振る舞いをサブクラスによって変えたいので、通常の静的メソッドは正しくありません。例については、Adam Francoの答えを参照してください。

1

単純なオブジェクト・リレーショナル・マッパー内に表(行インスタンス)を表すクラスがあるとします。 クラス "User"とクラス "Company"があり、そのインスタンスはそれぞれのテーブルの行を表しています。 ユーザーと会社は、いくつかの基本抽象クラスを継承します。save()、delete()、validate()などの一般的なメソッドを持つ "BaseObject"としましょう...

検証とテーブルの定義は、各派生クラスの静的変数に格納するのが最適です。なぜなら、検証とテーブルの定義はUserのインスタンスごとに同じであるからです。

LSBを使用しない場合、BaseObjectの前述のvalidate()メソッドは、UserおよびCompanyで定義された静的変数への参照を、Userのインスタンスを通じて呼び出す場合でもありません。 BaseObjectクラスで同じ静的変数が検索され、エラーが発生します。

これはPHP 5.2.8と私の経験である - LSB私はいくつかのフォーマットを処理する静的メソッドを持つクラスを持っている5.3

0

で導入されようとしています。私は、それがフォーマットをどのように扱うかを除いて、元のもののすべての機能性を必要とする別のクラスを持っています。

関連する問題