PHP 5.x で静的クラスを使用して Adapter パターンを実装する良い方法を探しています。
これを使用したい例の 1 つは、Python のos.path.join()
. Windows と Linux のアダプティ クラスの 2 つのアダプティが必要です。
これらのクラスには「コンテキスト」がないため、これらのクラスを静的クラスとして実装することは合理的だと思います。状態を保存する必要はなく、インスタンスが必要になるたびにインスタンスを作成するのは不必要に思えます。したがって、これを実装するクリーンな方法を探しています。
次の偽の実装を考えてみましょう。
static public function join(){
$parts = func_get_args();
$joined = array(MY_MAGICALLY_PASSED_DEFAULT_PATH_PREFIX);
foreach($parts as $part){
$part = self::$adaptee->cleanPath($path);
if(self::$adaptee->isAbsolute($part)){
$joined = array($part);
}
else{
$joined[] = $part;
}
}
return implode(PATH_SEPARATOR, $joined);
}
最初に気付くのは、必要な OS 依存の実装の詳細を保持する、adaptee と呼ばれる初期化された静的メンバーを想定していることです。
これには、クラスの宣言の直後に呼び出す任意の名前の静的コンストラクターのような関数が必要です。(このアプローチで気になるもう1つのこと)。
もちろん、$adaptee
各メソッド呼び出しでローカル変数を初期化することもできますが、それは不適切なようで、アダプティーを必要とする他の静的関数ごとに複製する必要があります。
さて... PHP のクラス実装の詳細: これらはファーストクラスのオブジェクトではないため、クラスを引数として渡すことはできませんでした。この例では、アダプティーを非静的(これを表す用語は何ですか?) クラスとして作成し、それをインスタンス化し、最終的に$adaptee
アダプター クラスの静的メンバー変数に割り当てる必要があります。
たぶん、これは私が持っているこの奇妙で完全に主観的な考えにすぎないのかもしれませんが、このようにするのは適切ではないと本当に感じています。より良い実装についてのアイデアはありますか?
私が持っていたもう1つのアイデアは、代わりにアダプティーのクラス名を保存し、代わりに使用するcall_user_func
ことですが、このアプローチを使用するのはあまり快適ではありません。
アップデート
これを適切に説明していない可能性があるため、更新でこれを説明しようとします。
基礎となるオペレーティング システムを取得する方法については調べていませんが、OS が Linux、Windows、FreeBSD、またはその他のいずれであるかによって、静的クラスが異なる動作をするためのきちんとした方法が必要です。
アダプターのパターンを考えたのですが、静的コンストラクターがないため、実際にはクラスを初期化できません。1 つの方法は、すべての public static メソッド呼び出しの開始時に初期化することです (または、初期化されているかどうかを確認するだけです)。
もう 1 つの可能性は、静的コンストラクターのようなメソッドを作成し、宣言の直後に呼び出すことです。それはうまくいくかもしれませんが、これを達成するために、他に、おそらくもっとエレガントな方法があるのではないかと思っています。
私の最初の例については、ユーティリティ関数であると想定されており、実際には状態を保持する必要がないため、どのような種類のパスオブジェクトも探していません。私が望むのは、呼び出されるたびに異なる OS を区別する必要なく、文字列を返す Path ファクトリ関数です。「ライブラリ」のことにより、関連するユーティリティ関数の疑似名前空間として静的クラスを作成し、アダプターパターンでサポートする必要があるさまざまな実装の詳細を作成しました。今、私は2つを組み合わせるエレガントな方法を探しています。