したがって、Flex の異なる基本クラスを拡張する 2 つのサブクラスがあり、これらを組み合わせて、同じことを繰り返さないようにする方法を教えてください。
基本的に私は次のようなものを持っています
public class A extends B {
// methods
}
public class C extends D {
// same methods as class A
}
これを組み合わせて、同じコードを2回繰り返さないようにする方法。
したがって、Flex の異なる基本クラスを拡張する 2 つのサブクラスがあり、これらを組み合わせて、同じことを繰り返さないようにする方法を教えてください。
基本的に私は次のようなものを持っています
public class A extends B {
// methods
}
public class C extends D {
// same methods as class A
}
これを組み合わせて、同じコードを2回繰り返さないようにする方法。
では、問題は、ソリューションをどのように構成する必要があるかということです。
1 つの可能性は、Decoratorパターンを使用することです。これは基本的に、既存のクラスのラッパーです。これを機能させるには、おそらくクラスで、ジョブを実行するために必要なものを公開するインターフェイスを実装する必要があります。
次のようなものです:
public interface IFoo {
function get name():String;
function set name(value:String):void;
}
public class A extends B implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
_name = value;
}
}
public class C extends D implements IFoo {
protected var _name:String;
public function get name():String {
return _name;
}
public function set name(value:String):void {
if (_value != _name) {
_name = value;
dispatchEvent(new Event('nameChanged'));
}
}
}
public class FooDecorator {
protected var _foo:IFoo;
public function FooDecorator(foo:IFoo) {
_foo = foo;
}
public function sayName():void {
trace('foo name is', _foo.name);
}
}
別の解決策は、動作をカプセル化する 5 番目の型の A と C の両方のメンバー変数を与えることです (ジェフリーが言ったように、可能であればデメテルの法則に従うことを好みます)。
class NameSayer {
function sayName(name:String):void {
trace('foo name is', _foo.name);
}
}
それから
public class A extends B {
public var name:String;
public var sayer:NameSayer;
//note that this method would be identical in both Classes
//but this is OK because the underlying logic is encapsulated
//and can be easily changed
public function sayName():void {
if (sayer) {
sayer.sayName();
}
}
}
多くの開発者は熱心に DRY に従うことに執着しすぎていると思います。Jeffry が言うように、これはアーキテクチャに他のさらに悪い問題を引き起こす可能性があります。これらのソリューションのどれが適切かは、何を達成しようとしているかによって異なります。
ただし、その使用については複雑な気持ちです。include ディレクティブを使用できます。
このように、sharedMethods.as (または任意の名前) という名前のファイルを作成します。これは実際のクラスではありません。コード スニペットが含まれているだけです。
public var mySharedMethod(mySharedMethodArguments:ArgumentType):void{
// do something
}
次に、それを他のクラスに含めることができます。
public class A extends B {
include "sharedMethods.as";
}
public class C extends D {
include "sharedMethods.as";
}
インクルード ファイルのコードは、クラス A およびクラス C の一部としてコンパイルされます。
共有コードを別のクラスに配置し、そのクラスのインスタンスを A と C の両方に配置することもできます。次に、ラッパー メソッドを記述するか、次のように呼び出しをドリルダウンする必要があります。aInstance.sharedCodeObject.sharedMethod();
私の直感は、あなたがこれにたくさん出くわした場合です。リファクタリングが必要なオブジェクト モデルに問題がある可能性があります。