2017-01-13 19 views
-1

私は、複数のクラスを持つコードをリファクタリングする必要があり、クラスのオブジェクトはユーザーの要求に応じて動的に作成する必要があります。今、クラスはすべてそこにあり、お互いに一致する共通のメソッドがありません。だから私はそれにインターフェイスを追加し、実際のクラスを参照するインターフェイス参照を返すファクトリクラスを作成することはできません。オブジェクトを動的に作成できるように、これをリファクタリングするジェネリックスやその他の方法がありますか?ここでのアプローチは、各クラスのオブジェクトがインスタンス化され、すべてのメソッドが呼び出されるメインクラスがあることです。私たちはシナリオにインターフェースやソリューションを持たないファクトリパターンを実装できますか?お願いします。インターフェイスを使用せずにFactoryPatternを実装するC#

シナリオを説明するサンプルコードを追加します。

public interface ITest 
{ 
    string TestMethod1(string st, int ab); 
    int TestMethod2(string st); 
    void TestMethod4(int ab); 
    float ITest.TestMethod3(string st); 
} 
public class Class1 : ITest 
{ 
    public string TestMethod1(string st, int ab) 
    { 
     return string.Empty; 
    } 
    public void TestMethod4(int ab) 
    { 
     throw new NotImplementedException(); 
    } 

    public int TestMethod2(string st) 
    { 
     throw new NotImplementedException(); 
    } 

    public float TestMethod3(string st) 
    { 
     throw new NotImplementedException(); 
    } 
} 
public class Class2 : ITest 
{ 

    float ITest.TestMethod3(string st) 
    { 
     return float.Parse("12.4"); 
    } 

    void ITest.TestMethod4(int ab) 
    { 
     throw new NotImplementedException(); 
    } 
    public string TestMethod1(string st, int ab) 
    { 
     throw new NotImplementedException(); 
    } 

    public int TestMethod2(string st) 
    { 
     throw new NotImplementedException(); 
    } 
} 
public class Main 
{ 
    ITest test = null; 

    public ITest CreateFactory(TestType testType) 
    { 
     switch(testType) 
     { 
      case TestType.Class1: 
       test = new Class1(); 
       break; 
      case TestType.Class2: 
       test = new Class2(); 
       break; 
     } 
     return test; 
    } 
} 

enum TestType 
{ 
    Class1, 
    Class2 
} 

したがって、上記のように、一般的な方法がないため、インタフェースを使用できません。だから私が空のインターフェースや抽象メソッドを持っていれば、他にどんな解決方法があるのか​​、それがどのように役立つでしょう。共通のメソッドをインターフェースに入れて、すべてのクラスが実装していても、インターフェースへの参照を渡しているので、インターフェース参照からしか共通のメソッドにアクセスすることはできません。

私の考えは、以下のようなものを使用することですが、戻り値の型が何であるか、または定義する必要があるかは不明です。私はお返しに、ここでTを定義するにはどうすればよい

public T CreateFactory(TestType testType) 
    { 
     switch(testType) 
     { 
      case TestType.Class1: 
       return GetInstance<Class1>("Class1"); 

      case TestType.Class2: 
       return GetInstance<Class1>("Class2"); 

     } 
     return null; 
    } 
    public T GetInstance<T>(string type) 
    { 
     return (T)Activator.CreateInstance(Type.GetType(type)); 
    } 

が私の関心事であると誰もがそれを助けることができるかどうか、私は、それを呼び出すことができ、その後、私は解に近いと思います。私は問題を理解し、それに打撃を与え、完全とは言わないよ、私の問題

public static T CreateFactory<T>() 
    where T: IFactory, new() 
{ 
    return new T(); 
} 
+0

はhttp://codereview.stackexchange.com 上のポストを作成したり、そうでない場合は、ここで をあなたのコードを貼り付けこれはちょうど理論的な議論です –

+0

どのように処理するか、またはどのメソッドを呼び出す必要があるのか​​(オブジェクトの作成後に)後でどのように知っていますか?その論理はあなたの問題を解決するのに役立ちます。 –

+0

これは私の問題です。私は、指定された型のオブジェクトを作成し、生成されたオブジェクトを返すクラスを持っていますが、返すためには、それをキャストするか変換するか、すべてのクラスで実装されたインタフェースを持っていなければなりません。私はここにインターフェイスを持つことはできませんbcoz一般的な方法はないので、私はこの場合何ができますか? – Blossom

答えて

1

回答...あなたが持っているクラスのような

工場:

class Factory 
{ 
    public static Visitable Create(string userInput) 
    { 
     switch (userInput) 
     { 
      case nameof(ClassA): 
       return new ClassA(); 
      case nameof(ClassB): 
       return new ClassB(); 
      default: 
       return null; 
     } 
    } 
} 

作成するタイプ:

class ClassA : Visitable 
{ 
    public void M1(){} 
    public override void Accept(Visitor visitor){visitor.Visit(this)} 
} 

class ClassB : Visitable 
{ 
    public void M2(){} 
    public override void Accept(Visitor visitor){visitor.Visit(this)} 
} 

コードの使い方:

var visitor = new Visitor(); 
var obj = Factory.Create("ClassA"); 
obj.Accept(visitor); 

行方不明の部品:これはVisitorパターンと呼ばれる

class Visitor 
{ 
    public void Visit(ClassA obj){ obj.M1(); } // Here you have to know what method will be called! 
    public void Visit(ClassB obj){ obj.M2(); } // Here you have to know what method will be called! 
} 

abstract class Visitable 
{ 
    public abstract void Accept(Visitor visitor); 
} 

。どのメソッドがVisitor.Visitと呼ばれる必要があるか分かっているなら、それはあなたが望むものです。

+0

これは私にとって初めてのことですが、私にとってはうまくいくとは思いません。たくさんのクラスがあり、それらが追加され続けているので、ここで変更を続けなければなりません。必要なのはスイッチとメソッドをインターフェイスに追加するだけです。 – Blossom

+0

少なくとも、あなたは正しい方法が分かっています:)私はあなたを助けることができる他のパターン/技法を知らない。たぶんいくつかの黒い魔法... これはパターンに関する良いサイトです:http://www.dofactory.com/net/design-patterns それを見て価値がある! –

+0

パターンマッチングはC#7の機能ですが、それを待たなければなりません。 –

0

私はあなたの質問を完全には理解していませんが、基本的な主張は間違っています。私はあなたの質問の基礎をあなたのデザインに関心を持っています。

かかわらず、私の提案された解決策:

あなたが共通のオブジェクト(間接を持っていないと言っているが、直接、あなたは次のように述べた。「共通の方法はそれにないので、私はインターフェイスを持つことができません。」

objectは共通要素です。

私はこれを許しませんが、ちょうどobjectをデータ型として返すファクトリオブジェクトを作成することができます。これに伴う問題あなたは、あなたが気にしないかもしれないオブジェクトの作成後にそれをキャストする必要があります...

internal class MyFactory 
{ 
    internal object CreateItem1() { return ...; } 
    internal object CreateItem2() { return ...; } 
    internal object CreateItem2(ExampleEnum e) 
    { 
     switch(e) 
     { 
      case e.Something: 
       return new blah(); 
      default: 
       return new List<string>(); 
     } 
    } 

} 
+0

私が持っているものは単純な工場パターンです、誰がそれを理解できないのかわかりません、ここで必要な私の唯一の変更は、一般的なものかもしれない、しかし私はそれを実装する方法を知らない。 – Blossom

+0

それは私の提案です。宣言にかかわらず(暗黙のうちに)CLR(.NET)内のすべてのオブジェクトの基底である 'object'を使用してください。私の場合、私は目的を理解していません。オブジェクトの種類を予測できない場合は、オブジェクトを正しく設計していない可能性があります。非常に大きな話題ですが、あなたの理由が何であれ、私の答えは、あなたがコメントしたことに基づいて適切でなければなりません。 –

+0

しかし、受信側では、送信するオブジェクトからどのタイプに変換するのかをどのように知っていますか? – Blossom

関連する問題