2011-02-04 4 views
4

は、我々は上向き(例TdmBasicDataに)特定のクラスを検索するには、次の構文オブジェクトが所有者の多くを知っている場合は、コードのにおいですか?私たちのデルファイ2007アプリケーションで

FdmBasic:=TdmBasicData(FindOwnerClass(AOwner,TdmBasicData)); 

FindOwnerClassは、現在のコンポーネントの所有者の階層を移動するの多くを使用しています。結果のオブジェクトは、Field変数FdmBasicに格納されます。これは、主にデータモジュールを渡すために使用します。

例: レポートを生成すると、結果のデータは圧縮され、データモジュールTdmReportBaseDataを介してアクセスされるテーブルのBlobフィールドに格納されます。アプリケーションの別のモジュールには、ReportBuilderを使用してレポートからのデータをPaged形式で表示する機能があります。このモジュール(TdmRbreport)のメインコードは、クラスTRBTempdatabaseを使用して、圧縮BLOBデータをReportbuilderランタイムreportdesignerで使用可能な異なるテーブルに変換します。 TdmRbreportは、あらゆる種類のレポート関連データ(レポートの種類、レポートcalculationsettingsなど)のTdmReportBaseDataにアクセスできます。 TRBTempDatabaseはTdmRbreportで構築されますが、TdmReportBasedataにアクセスできる必要があります。

constructor TRBTempDatabase.Create(aOwner: TComponent); 
begin 
    inherited Create(aOwner); 

    FdmReportBaseData := TdmRBReport(FindOwnerClass(Owner, TdmRBReport)).dmReportBaseData; 
end;{- .Create } 

私の気持ちは、これはTRBTempDatabaseは、その所有者の多くを知っていることを意味していることであり、これはコードのにおいやアンチパターンのいくつかの並べ替えがある場合、私は思っていた:これは今の上に建設を使用して行われます。

これについてのご意見はありますか?これはコードのにおいですか?もしそうなら、もっと良い方法は何ですか?

+0

コードのにおい? :)) http://en.wikipedia.org/wiki/Code_smell – Shinnok

+2

それは可能性があります。 *現在のオブジェクト*を単体テストするのはどれくらい簡単ですか?所有者の依存関係のために難しい場合、私はそれを扱うものと考えています。あなたはDependancy Injectionで構造体を置き換えることができます。 –

+0

@Lieven - 私たちはユニットテストをしていません。実際には私はそれについて読んで始め、それについて非常に熱心になってきました。この読書が私に上記の構造について考えさせてくれたと思う... – Bascy

答えて

5

ここに記載されている説明では、これを軽度に臭いとみなしています。ただし、修正するのは簡単です。

私はdmReportBaseDataオブジェクトを必要とするコンポーネントのコンストラクタに渡す傾向があります。これにより、現時点で実行時に強制的に実行するのではなく、コンパイル時に契約が明確になります。

現在のところ、強制する契約は、必要以上に強くなっています。 TRBTempDatabasedmReportBaseDataインスタンスのみを必要としますが、TdmRBReportレポートオブジェクトからそのインスタンスを取得できる場合にのみ機能します。

この変更を行うと、TRBTempDatabaseTdmRBReportは離婚しても正常に機能します。 @Lievenはコメントの中で指摘しているように、テストを簡単にするでしょう。

+0

ヘフマン - ありがとうございます。 – Bascy

+0

@Bascyよろしくお願いします。ところで良い質問です! –

2

基本クラスで行っていることは、親オブジェクトへの参照を維持している場合はいいえ、コード匂いではないことは完全に正当な使用です。 「後で来るかもしれないもの」に関する情報を伝達するために、明示的に基本クラスを設計することができます。

基本クラスがそれ自体に存在しない派生クラスの特性に依存している場合(つまり、一般化されたクラスはその子のうちの1つの特殊化に依存しています)、それはちょっとファンキーです。

+0

私は非常に正確ではなかった与えた例に気づいた、それを修正しました。場合は、基本クラスが派生クラスについて何かを知っているというわけではありません。それは本当にその親(所有者/創造者)について何かを知っています。あなたはそれが「完全に合法」であると述べていますが、Lievenのように暗黙の依存関係のために単体テストをより困難にしなければならないと言いましたか? – Bascy

+1

@Bascy:従属性を明示的*にして、その子が親/工場の公開契約のみを使用するようにするのは良い理由です。それ以降コードが依然として匂いがするかどうかは、答えの範囲外です。 –

+0

@Bascy - 質問を更新したので私の答えはちょっと残っていると思いますが、私が「明示的にデザインする」と言うときは、コンパイル時に強制できる契約を指定することを意味します。デビッドの答えは素晴らしいです。なぜなら、それは非常に軽くて簡単に維持できる方法であるからです。暗黙的な依存関係(つまり、仮定)では、単体テストが失敗するが、必ずしもそうとは限りません。そうすれば、エラーを見つけるためにコンパイラに頼るほうがよいでしょう。 – par

関連する問題