2016-10-30 7 views
1

は、次のことを想像:私は関連するすべての関連のロジックとオーケストレーションをカプセル化している1つのクラスを持っているよりも、私はのFooクラスOO - 定型/転送コードを削減

class Foo { } 

    class FooA : Foo { } 

    class FooB : Foo { } 

    class FooX : Foo { } 

から継承DTOのの束を持っていますFooデータ型。

void DoSomething(Foo data) 
{ 
    if (data is FooA) 
      DoSomethingWithFooA((FooA) data); 
    if (data is FooB) 
      DoSomethingWithFooB((FooA)data); 
    if (data is FooX) 
      DoSomethingWithFooC((FooA)data); 
} 

これは非常に単純化した例である:私は、メソッドの実装は、このようなものである引数

によって提供されたデータに関連するすべてのロジックを実行する方法DoSomethingWithData(Foo data)を提供します。このアプローチの利点は次のとおりです。私は新しいタイプを追加する場合

  • は、私が唯一の方法DoSomething
  • に変更する必要が

    • 「クライアント」は、独立して Fooデータ型の常にDoSomethingメソッドを呼び出します

      ダウンキャスティングが好きでないもの

      代わりに、DoSomethingの方法を公開するのではなく、データ型。利点は、ダウンキャストはありませんが、定型句/転送コードが増加することです。

      あなたは何をお選びくださいか?それとも他のアプローチがありますか?

    +0

    私はこのデザインパターンを適切に解決するC++と仮想メソッドを使用することをお勧めします。 –

    +0

    これは主に異なる意見についてだと思います。ロバート・マーティンの「クリーン・コード」を調べたいと思うかもしれません。彼は「データ転送オブジェクト」とその長所と短所に関する全章を持っています。 – GhostCat

    答えて

    1

    この場合、私はこのような問題にアプローチします(この例ではJavaを使用します)。

    Fooのすべてのサブクラスに対して、示されているように特定の処理ロジックを提供し、Fooオブジェクトをそのサブタイプにキャストする必要があります。さらに、追加する新しいクラスごとに、DoSomething(Foo f)メソッドを変更する必要があります。

    あなたはinterfaceFooクラス加えることができますように

    public class FooA iplements Foo { 
        public void doSomething(){ 
         //Whatever FooA needs to do. 
        } 
    } 
    
    public class FooB implements Foo { 
        public void doSomething(){ 
         //Whatever FooB needs to do. 
        } 
    } 
    

    そして:あなたのクラスは、このインタフェースを実装する必要がありその後

    public interface Foo{ 
        public void doSomething(); 
    } 
    

    を。

    ... 
    Foo fooA = new FooA(); 
    Foo fooB = new FooB(); 
    
    fooA.doSomething(); 
    fooB.doSomething(); 
    ... 
    

    この方法では、あなたが実行時にオブジェクトをキャストする必要はありません、あなたはより多くのクラスを追加する場合、既存のコードを変更する必要はありません。そして、クライアントはdoSomething()メソッドを呼び出すことができますただし、新しく追加されたオブジェクトのメソッドを呼び出す必要があるクライアントは例外です。

    関連する問題