1

注: 私のコードはたまたま C# で書かれていますが、問題を解決する上で重要だとは思いません。

問題

XML からクエリをロードするために使用される 2 つの古いクラスで、コードの重複を削減しようとしています。どちらも XML の場所を取得するコンストラクターを持ちExecute、SQL パラメーターのコレクションを受け入れるメソッドを持ち、さまざまな静的オーバーロード メソッドを提供して、単一の名前付きパラメーターを使用して、またはパラメーターを使用せずに、または 1 つのクエリをすばやく簡単に実行できるようにします。デフォルト以外の SQL 接続オブジェクトを使用します。これらの静的メソッドも XML の場所をパラメーターとして受け入れ、内部的にコンストラクターなどを呼び出して、最終的に DataSet の最初の DataTable を返すだけです。

public static DataTable GetQuery(string queryName) { ... }
public static DataTable GetQuery(string queryName, string parameterName, string parameterValue) { ... }
public static DataTable GetQuery(string queryName, Hashtable parameters) { ... }
public static DataTable GetQuery(string queryName, Hashtable parameters, IConnection connection) { ... }

等々。

2 つの違いは、1 つはファイル システム内の XML ファイルを検索し、もう 1 つはアセンブリに埋め込まれた XML ファイルを検索することです。

考えられる解決策 1

IQuerySource私はそれらを、コンストラクターに渡された別のインターフェースの異なる実装を使用して、または何かを実行できるものに統合することを考えていました。ただし、これは、コンストラクターを常に事前に呼び出す必要があるか、メソッドに毎回オブジェクトGetQueryを渡す必要があることを意味します。IQuerySourceこれらのGetQueryメソッドはクライアント コードのいたるところGetQuery("GetUserDetails","UserID",userId.ToString())で使用されているため、 .

考えられる解決策 2

別の方法として、2 つの非常に軽量なクラス と を作成しFileQueryて、統合クラスの上に配置し、常にコンストラクターやメソッドに受けDllQuery渡します。これにより、クライアント コードを小さく保つことができますが、コア クラスに加えて、さらに 2 つの場所で既存のすべてのオーバーロードの (わずかに薄い) バージョンを維持する必要はありません。FileQuerySourceDllQuerySourceGetQueryGetQuery

考えられる解決策 3

別の代替手段は上記のようになりますが、統合クラスを公開して、たとえば を呼び出すことができますが、DllQuery.Q.GetQuery("GetUserDetails","UserID",userId.ToString())DllQuery が呼び出しをインターセプトし、統合クラスの Q インスタンスが常に適切なソースを取得できるようにする方法がわかりません。仕事。

さらに複雑なのは、アセンブリから XML を取得するために現在 を使用しているSystem.Reflection.Assembly.GetCallingAssembly()ため、それが呼び出される場所はどこでも、クライアント コードの表面のすぐ下に配置する必要があります。そうしないと、クライアント アセンブリではなく Data アセンブリを取得します。

この質問が少し主観的かもしれないことは理解していますが、これに対処するための、よく理解され、明確に定義された設計パターンまたは何かがあることを願っています。

4

1 に答える 1

2

これは意見にかなり左右されると思いますが、私はこれを行います:

public interface IQuerySource
{
  // function GetXML(Assembly caller)
};

public class XmlQuery
{
  XmlQuery(IQuerySource source);
  // GetQuery functions
}

public class FileQuery : IQuerySource
{
  private FileQuery() {} // Only accessable through the Q property
  public static readonly XmlQuery Q = new XmlQuery(new FileQuery());

  // function GetXML(Assembly caller) for a file source
}

public class DllQuery : IQuerySource
{
  private DllQuery() {} // Only accessable through the Q property
  public static readonly XmlQuery Q = new XmlQuery(new DllQuery());

  // function GetXML(Assembly caller) for an assembly source
}
于 2012-07-13T15:09:43.917 に答える