2

使用しなければならないかなり特殊なデータソース(実際には会計アプリケーションへのインターフェイス)があります。それはかなり強力ですが、私はそれから必要なデータを取得するためにかなり多くのフープを飛び越えなければなりません。たとえば、テーブルの内容を取得して、返す列を指定する場合は、.Columnsコレクションを反復処理して、必要な列に対して.SetVisible()を呼び出す必要があります。

現在、これをラップしてより簡単な方法で指定できるメソッドがありますが、その関数のパラメーターリストは急速に増えており、ほとんどの場合、呼び出すときにいくつか指定するだけで済みます。 。要するに、それは柔軟性のない解決策です。

私の頭に浮かんだ最初の解決策は次のようなものでした。

DataTable result = DataSourceWrapper.StartQuery("TableName")
    .SetVisibleColumns("Col1", "Col2", "Col3")
    .SetCriteria("CriteriaName", "Param1Name", CriteriaParam1, "Param2Name", CriteriaParam2)
    .SetFilter("Col4 = ? AND Col5 = ?", FilterParam1, FilterParam2)
    .SetReportParams("Param1Name", ReportParam1, "Param2Name", ReportParam2)
    .Execute();

Criteria、Filters、およびReportParamsはアプリケーションに固有のものであり、ここではそれらについては説明しません。しかし、一般的な考え方はこのようなものです。これは、メソッドの呼び出しと実質的に類似していますが、(特定のメソッドを呼び出すことによって)指定するパラメーターを選択でき、IntelliSenseの支援が少し増える点が異なります。また、メソッド呼び出しの順序を試すこともできます。

SetFilter()解析する式があることに注意してください。これは、データソースが困難にするもう1つのことです。式を非常にうまく処理できますが、それらを特別なオブジェクトのツリーとして渡す必要があります。これも、作成にかなり時間がかかります。の質問で、私はそのような式を解析するのに助けを求めました。現在のラッパーメソッドには、単純な式を解析できる自作式パーサーがありますが、それらのサポートをより完全にすることを考えました。

その質問では、Ironyプロジェクトが提案されました。それをチェックした後、私はそれが本当にこのニーズに適していると判断しました。しかし、しばらくすると、それはそれよりもさらに強力であることに気づきました。自分のクエリ言語をこのタスクにぴったりと合わせてみませんか?上記は次のようになります。

DataTable result = DataSourceWrapper.Query(@"
    SELECT Col1, Col2, Col3
    FROM TableName
    WITH CRITERIA CriteriaName(Param1Name={0}, Param2Name={1})
    WITH REPORTPARAMS (Param1Name={2}, Param2Name={3}
    WHERE Col4 = {4} AND Col5 = {5}",
    CriteriaParam1, CriteriaParam2,
    ReportParam1, ReportParam2,
    FilterParam1, FilterParam2
);

しかし...これはやり過ぎではないでしょうか?どちらのアプローチの長所と短所は何ですか?私が見ているのは:

プロDSL:

  • より簡潔なクエリ。

プロの方法:

  • より多くのIntelliSenseサポート。
  • メソッド名/パラメーター名(およびコメント)により、文書化の必要性が少なくなります(DSLは完全に文書化する必要があります)。
  • 作成するのが速いかもしれませんか?私は自分でDSLを作成したことがないので、それがどれだけの作業であるかわかりません。アイロニーは私の肩から多くの負担をかけているようですが、まだどれくらい残っていますか?

追加:明確にするために、両方のアプローチはコーダーによってのみ使用されます。外部の人やビジネスアナリストはそれを使用しません。

4

2 に答える 2

2

DSLと呼ぶものに注意する必要があります。DSLに関するMartinFowlerのBliki投稿を参照してください。メソッドチェーンの例は、内部DSLに非常に近いものです。少し変更すると、次のようになります。

DataTable result = DataSourceWrapper.Query("TableName")
    .With(new Columns("Col1", "Col2", "Col3"))
    .Where(new AndCritera("CriteriaName",
        new Criterion("Param1Name", CriteriaParam1),
        new Criterion("Param2Name", CriteriaParam2))
    .Filter(
        new Filter("Col4").Equals(FilterParam1),
        new Filter("Col5").Equals(FilterParam2))
    .With(
        new ReportParam("Param1Name", ReportParam1),
        new ReportParam("Param2Name", ReportParam2));

そうは言っても、これはまだC#の領域内にあり、プログラマーだけがこれらのクエリを記述できます。要件がプログラマー以外の人がクエリを利用できるようにする方向に進んでいる場合は、2番目の例で指定したように外部DSLを作成する作業を検討することをお勧めします。

于 2009-04-22T18:39:16.860 に答える
0

私はDSLアプローチを選びます。

理由:1個人的な経験から、ドメインの専門家に近く、DSL形式のBAのようなものであり、ビジネス志向の人々と開発者の間のコミュニケーションの障壁を打ち破り、2次のようなツールを使用して技術仕様を作成するのがはるかに簡単になります。皮肉なことに、DSLは明確に定義されており、DSLを実装するテスト駆動型開発3の良い候補には、開発者に関する最初の学習が少し必要です(私は、Ironyよりもさらにフレンドリーではないjavaccを使用しました)が、アイデアを理解したら、ロジックをDSLにオフロードするため、コードは簡単になり、コードは非常に一般的になります。

于 2009-04-22T18:35:06.883 に答える