0

したがって、Flex の異なる基本クラスを拡張する 2 つのサブクラスがあり、これらを組み合わせて、同じことを繰り返さないようにする方法を教えてください。

基本的に私は次のようなものを持っています

public class A extends B {
 // methods
}

public class C extends D {
 // same methods as class A
}

これを組み合わせて、同じコードを2回繰り返さないようにする方法。

4

3 に答える 3

1

継承よりも構成を優先する

では、問題は、ソリューションをどのように構成する必要があるかということです。

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 が言うように、これはアーキテクチャに他のさらに悪い問題を引き起こす可能性があります。これらのソリューションのどれが適切かは、何を達成しようとしているかによって異なります。

于 2013-02-08T06:08:30.823 に答える
0

ただし、その使用については複雑な気持ちです。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();

私の直感は、あなたがこれにたくさん出くわした場合です。リファクタリングが必要なオブジェクト モデルに問題がある可能性があります。

于 2013-02-07T18:24:51.063 に答える