遅い静的結合(LSB)のthis descriptionを読んだ後、私はかなり明確に何が起こっているかを見ます。今、どのような状況下で、それが最も有用で必要なのでしょうか?いつ遅い静的バインディングを使用する必要がありますか?
答えて
私はLSB次のシナリオについては、この必要:その後、
- あなたは電子メールサーバーからメッセージをダウンロードする「メールプロセッサ」デーモンを構築している想像し、それを分類し、それを解析し、それを保存し、メッセージの種類に応じて何かを行います。
- クラス階層:基本メッセージクラスがあり、子 "BouncedMessage"と "AcceptedMessage"があります。
- それぞれのメッセージタイプには、ディスク上にそれ自身を保持する独自の方法があります。たとえば、BouncedMessageタイプのすべてのメッセージは、BouncedMessage-id.xmlとして自身を保存しようとします。一方、AcceptedMessageは、AcceptedMessage-timestamp.xmlのように、それ自体を別々に保存する必要があります。ここで重要なのは、ファイル名パターンを決定するロジックがサブクラスによって異なりますが、はサブクラス内のすべてのアイテムに対してを共有しています。それが静的な方法であることが理にかなっている理由です。
- 基本メッセージクラスには、抽象的な静的メソッド(yes、abstract および静的)の「保存」があります。 BouncedMessageは、このメソッドを具体的な静的メソッドで実装します。その後、実際にメッセージを取得し、クラスの内部で、あなたが呼び出すことができます "::(保存)"
あなたは主題についての詳細を知りたい場合:
オーバーロードされた静的プロパティ/メソッドにアクセスする必要がある場合サブクラスでオーバーロードされています - あなたは遅い静的バインディングが必要です。簡単な例:あなたはこのようになります。これは、PHPで同様のものを実装しようとした場合paste2.org
は、古典的な例は、RailsのからのActiveRecordクラスです:class User extends ActiveRecord
、その後、実際にActiveRecord::find()
で呼び出されるUser::find(1)
メソッドを呼び出そうあなたはUser
でfind()
をオーバーロードしていないので - しかしActiveRecord
にfind()
方法を結合後半静的ずにそれが(それは常にActiveRecord
を指します内self
)から呼ばれました分類を知る方法がないので、それがフェッチすることはできませんあなたあなたのためのユーザーオブジェクト。
私が遅い静的バインディングを必要とする主なものは、静的インスタンス作成メソッドのセットです。
この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はこの重複を減らし、よりクリーンで簡単な実装を可能にします。
それはときに便利です:あなたはクラス階層にわたって変化する機能を持っている
、
機能は、あなたが(決定的)階層の上に同じシグネチャを持っており、
機能をオフにするインスタンスはありません。
#1と#2だけが得られた場合は、通常のインスタンスメソッドを使用します。だからアレックスの問題(この質問に対する彼の答えを参照)はLSBを必要としません。
典型的なケースは、サブクラスが異なる方法で自身を作成するが、同じパラメータを使用するオブジェクト作成です。明らかに呼び出すインスタンスがないので、作成メソッド(ファクトリメソッドとも呼ばれます)は静的でなければなりません。しかし、その振る舞いをサブクラスによって変えたいので、通常の静的メソッドは正しくありません。例については、Adam Francoの答えを参照してください。
単純なオブジェクト・リレーショナル・マッパー内に表(行インスタンス)を表すクラスがあるとします。 クラス "User"とクラス "Company"があり、そのインスタンスはそれぞれのテーブルの行を表しています。 ユーザーと会社は、いくつかの基本抽象クラスを継承します。save()、delete()、validate()などの一般的なメソッドを持つ "BaseObject"としましょう...
検証とテーブルの定義は、各派生クラスの静的変数に格納するのが最適です。なぜなら、検証とテーブルの定義はUserのインスタンスごとに同じであるからです。
LSBを使用しない場合、BaseObjectの前述のvalidate()メソッドは、UserおよびCompanyで定義された静的変数への参照を、Userのインスタンスを通じて呼び出す場合でもありません。 BaseObjectクラスで同じ静的変数が検索され、エラーが発生します。
これはPHP 5.2.8と私の経験である - LSB私はいくつかのフォーマットを処理する静的メソッドを持つクラスを持っている5.3
で導入されようとしています。私は、それがフォーマットをどのように扱うかを除いて、元のもののすべての機能性を必要とする別のクラスを持っています。
- 1. いつ静的メソッドを使用する必要がありますか?
- 2. デリゲートのプレフィックスをいつ「静的」にする必要がありますか?
- 3. ストリームはいつ遅延する必要がありますか?
- 4. いつglInvalidateBufferDataを使用する必要がありますか?
- 5. いつWS_EX_NOREDIRECTIONBITMAPを使用する必要がありますか?
- 6. SafeValueは、[プロパティ]を使用する必要があります=バインディング:
- 7. Springアプリケーションのユーティリティクラス - 静的メソッドを使用する必要がありますか?
- 8. アーキテクチャデザインパターンはいつ使用する必要がありますか?
- 9. wkWebViewはいつ使用する必要がありますか?
- 10. InverseBindingAdapterはいつ使用する必要がありますか?
- 11. 静的でないクラスメンバーがない場合、クラスを静的にする必要がありますか?
- 12. ラムダを静的にする必要がありますか?
- 13. いくつかの関数をオーバーライドしますcakephp(遅い静的バインディング)
- 14. 新しい自己または新しい静的を使用する必要がありますか?
- 15. いつnn.ModuleListを使用する必要がありますか?また、いつnn.Sequentialを使用する必要がありますか?
- 16. 静的ベクトルは削除する必要がありますか?
- 17. いつasp.netクラスの静的関数を書く必要があります
- 18. ヘルパーメソッドはC#で静的クラスを使用する必要があります
- 19. selfパラメータを使用しないすべてのメソッドを静的クラスにする必要がありますか?
- 20. C#LINQターゲットは静的である必要があります
- 21. ポーリングクラスを静的にする必要があります
- 22. 静的メソッドと非静的メソッドでインスタンスを使用する必要があります
- 23. RouteConfig.csは静的クラスにする必要があります
- 24. $ scope.apply()を使用する必要があります。遅い場合があります。
- 25. 2つの静的テキストフィールドでグリッドビューを作成する必要があります
- 26. 静的なワークプールまたは(スレッドの)動的ワークプールを使用する必要がありますか?
- 27. SafeValueは[プロパティ] =バインディングを使用する必要がありますが、ITは
- 28. 私的静的メソッドの必要性はありますか?
- 29. プログラムが静的であってもエラー処理を使用する必要がありますか?
- 30. webpackを使用しているときに静的ファイルを生成する必要はありますか?
この場合の* why *を追加することができれば、 '' 'static ::' ''は単純に抽象的な*非static *メソッドを使うよりも簡単になるでしょう。私にとっては、 '' save() ''は、とにかく静的コンテキストから呼び出す理由がないが、おそらく何かが欠けているようだ。 – SeldomNeedy