シナリオ
別のコンポーネント(レポートビルダー)に送信する動的クエリビルダーを作成しています。
クエリの一部にはプレースホルダーがあります。例えば:
SELECT DISTINCT ID, NAME AS VALUE FROM EVENTS
WHERE {{ESTABLISHMENTFILTER.ID}} IS NULL OR ESTABLISHMENT_ID = {{ESTABLISHMENTFILTER.ID}}
where句で置き換えられるデータは、整数、文字列、日付にすることができ、それぞれの動作が異なります(たとえば、文字列の場合は値を一重引用符で囲みます)。
私の最初のアプローチは、列挙型を作成することでした。
public enum FilterType
{
Integer,
String
}
このように使用します(たとえば、ビジネス層で)
switch (filter.Type)
{
case FilterType.Integer:
//Do replace logic for an integer
break;
case FilterType.String:
//Do replace logic for a string
break;
default:
break;
}
また、コードにSOLIDの原則を適用していますが、これによりOCPが破損する可能性があることがわかりました。だから私は基本クラスを使用するようにリファクタリングしました
public abstract class FilterType
{
public abstract string Replace(string baseString, string oldValue, string newValue);
}
各タイプには独自の実装があります。
public class FilterTypeInteger : FilterType
{
public override string Replace(string baseString,string oldValue, string newValue)
{
//Do logic to replace for an Integer type
}
}
問題
SOLIDソリューションは私のテストでは機能しましたが、本番コードでは、データベースにタイプを判別するためのint列があります。したがって、基本的に「switch-case」ロジックをデータレイヤーに転送します。データレイヤーは、この列をチェックして正しいFilterTypeをインスタンス化する必要があります(以下のコードは、まだ実装していないため、疑似コードです)。
if (dataReader["FILTERTYPE"] == 1)
filter.Type = new FilterTypeInteger();
else if (dataReader["FILTERTYPE"] == 2)
filter.Type = new FilterTypeString();
質問
1)上記の「if-else」ロジックを実装するメソッドはOCPを破っていますか?新しいTypeを作成する場合は、新しいelse句を実装する必要があるためです
。2)switch ou if-else句を使用せずに、データベースとビジネスコードの両方にSOLID OCPの原則を維持する別のアプローチはありますか?
条件付きをpolymorphysimに置き換えると、意思決定が1回だけ行われるようになるため、おそらくそれは良い考えです。ある時点でタイプごとに追加の特殊な操作がある場合、それらは簡単に実装できるはずです。
ここで、具象型を作成するために、このロジックをファクトリにカプセル化できます。最も単純な形式では、ファクトリは大きなswitchステートメントを持つ静的なものになります。OCPを尊重しませんが、それでもほとんどの場合、許容できる設計です。
ただし、設計上および実行時に拡張可能にしたい場合は、拡張できないため、実行時に新しい型を検出/登録できる方法を導入する必要があります。
これはさまざまな方法で実行できますが、例として、新しい型を登録できるメソッドをファクトリに用意します。
例えば
filterTypeFactory.RegisterFilter(1, typeof(FilterTypeInteger));
とにかく、独自のSQLステートメントビルダーを所有して構築する前に、既存のライブラリを確認する必要があります。ASTに解析されてからこのASTを処理してSqlCommandなどを生成する中間DSL(テンプレート)がある場合があります。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加