シナリオこのシナリオで列挙型に対して多型を使用する利点はありますか?
私は別のコンポーネント(レポートビルダ)に送信する動的なクエリビルダを作成しています。
クエリの一部にプレースホルダがあります。例えば:
SELECT DISTINCT ID, NAME AS VALUE FROM EVENTS
WHERE {{ESTABLISHMENTFILTER.ID}} IS NULL OR ESTABLISHMENT_ID = {{ESTABLISHMENTFILTER.ID}}
データ句は整数、文字列、日付とすることができ、それぞれが、例えば、異なる挙動を有する(ここで置換される:文字列の値の周囲に一重引用符を含みます場合)。 、
public enum FilterType
{
Integer,
String
}
、私はまた私のコードにSOLID原則を適用しています
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;
}
(例えば、ビジネス層に)このようにそれを使用します。
私の最初のアプローチは、列挙型を作成することでしたこれが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
}
}
固溶体は、私のテストのために働いていた問題が、生産コードでタイプを決定するためのint列がデータベースにあります。だから、私は基本的には、適切なFilterTypeをインスタンス化するためにこの列をチェックしなければならないdatalayerにswitch-caseロジックを転送しています(まだ実装されていないので、以下のコードは擬似コードです):
if (dataReader["FILTERTYPE"] == 1)
filter.Type = new FilterTypeInteger();
else if (dataReader["FILTERTYPE"] == 2)
filter.Type = new FilterTypeString();
質問
1)上記 'のif-else' ロジックを実装する方法は、OCPを壊していますか?新しいTypeが作成された場合は、新しいelse節を実装する必要があります
2)ou if-else節を使用せずにSOLID OCPの原則をデータベースとビジネスコードの両方に保持する方法がありますか?
SQL文を作成する場合は、ライブラリとその準備文を使用してそれらの処理を行うのはなぜですか? – Seth
クエリは既存のユーザーインターフェイスを通じて作成されるため、テンプレートに定義されたプレースホルダをサポートする必要があります。また、カスケードクエリをサポートする必要があります。そのため、自分のコンポーネントをビルドすることにしました。 –