3

、、、などのCommonDaoOperationsいくつかのジェネリック メソッドを含むユーティリティ クラスを作成しています。一部の DAO はより複雑で、これらのジェネリック メソッドを使用できないため、これは基本クラスではありませんが、多くの DAO は使用できます。CreateUpdateDelete

私は今、そのユーティリティクラスが正確にどのように見えるべきかを考えています:

  • 静的ジェネリック メソッドのみを持つ静的クラス
  • プライベートな読み取り専用メンバーとして DAO ごとに 1 回作成される、ジェネリック メソッドを持つ通常のクラス
  • DAO メソッドごとに 1 回 (各呼び出しで) 作成される、ジェネリック メソッドを持つ通常のクラス

DAO/メソッドごとにクラスのインスタンスを作成すると、明らかに静的メソッドを呼び出すよりもコストがかかりますが、これらのコストはほとんどすべてのアプリケーションで無視できると確信しています。

非静的クラスの利点があるため、ソリューション2または3を好みます(インターフェイス、モック可能、派生/拡張可能、必要に応じて将来コンストラクターを介してパラメーターを収集できます(10パラメーターと比較して)メソッド)))。

したがって、本当の問題は、ユーティリティ クラスをメンバー変数として作成する必要があるのか​​、それとも DAO メソッドごとにインスタンス化する必要があるのか​​ということです。

public void Create(User user) { 
   new CommonDaoOperations().Create(user);
}
public void Delete(User user) {
   var daoOps = new CommonDaoOperations();
   daoOps.CheckSomething(); // just an example of multiple calls to the class
   daoOps.Delete(user);
}

他の開発者がこれらのアプローチのいずれかについてどう考えているか、またはこれを行うための別の/より良い方法がまだあるかどうかに興味があります.

編集

アプローチ#3をもっと考えるべきだったことに気付きました-Vadimが指摘したように、各メソッドでインスタンス化されたときに具象クラスを置き換えるのは面倒ですが、プロパティでそれを考慮することができます:

private CommonDaoOperations DaoOps {
    get { return new CommonDaoOperations(); }
}
public void Create(User user) {
   DaoOps.Create(user);
}

これは上記のスニペットよりも保守しやすいと思いますが、DAO に「ユーティリティ」クラスのプロパティを導入したことを知っています。これは、それ自体がコードの匂いである可能性があります (Ant P が指摘したように)。

概要

これは難しい決断でした。私は Ant P からの回答を受け入れましたが、Vadim の回答も正当です。どのアプローチを使用するかは、ユーティリティ クラスによって異なります。3 つのアプローチすべてに用途があります(更新された #3 を除く)。少なくとも、それは提供された回答に対する私の見解です。

  • 静的クラスには用途がありますが、上で簡単に説明したように多くの欠点もあります。
  • メソッドごとにインスタンス化された通常のクラス:ユーティリティ クラスが作成され、必要な場所でのみ使用されます。依存関係を減らし、型を純粋に保ちます。
  • メンバーとしてインスタンス化された通常のクラス:多くの/すべてのメソッドがユーティリティ クラスのインスタンスを必要とする場合、メンバー変数を作成することをお勧めします。このようにして、タイプまたはインスタンス化の方法を変更するのが簡単になります。
4

3 に答える 3

2

これらのオブジェクトを非常に多く作成する予定がない限り、パフォーマンスに影響はないと思います。

(2)の方がいいと思います。使用するたびに作成する必要があるだけです。それはただのコードを書くだけです。さらに、何らかの IOC を使用したい場合は、ユーティリティ クラスをパラメーターとして取得し、初期化方法を変更するか、単にクラスを別のクラスに変更します。単一のメンバーを変更するのは、それが使用されるすべての場所を変更します。

よほどの理由がない限り、スタティックやシングルトンには近づかないでください。(非常に適切な理由の例としては、クラスの初期化および使用方法を制御できないアドオンまたはプラグインの開発などがあります)。

于 2013-07-26T07:25:50.870 に答える
2

パフォーマンスへの影響について、より適格なコメントをさせていただきます。ただし、それぞれについての私の考えは次のとおりです。

1.静的クラス

この概念は、実際の拡張性を必要としない単純で「包括的でない」ユーティリティ メソッドには適していますが、お気づきのように、一般的な DAO 操作はかなり洗練されたものになります。これは、特に複数の異なるタイプの DAO で使用される場合、単一の静的クラスとして非常に扱いやすいとは言えません。

2. 具象クラス、インスタンス化された DAO オブジェクトごと

これはすべて問題ありませんが、ユーティリティ クラスを個々の DAO のメンバーにする必要があるでしょうか。DAO の存続期間全体にわたって、ユーティリティ クラス内である種の一貫性または状態の永続性が必要な場合、これは理解できますが、これらのメソッドはかなり漠然としているようです (「ユーティリティ」クラスとしての名前に忠実です)。

メソッドごとにインスタンス化された具象クラス。これは私にとって最も自然な解決策のようです。これにより、オブジェクトのスコープを必要な場所 (個々のメソッド呼び出し) に制限しながら、質問で認めた具象クラスのすべての利点を柔軟に利用できます。

クラスが DAO 全体で必要とされるものに発展した場合、たとえばオブジェクトの状態を突然維持する必要が生じた場合 (または、オブジェクトを DAO のコンストラクターに注入する必要がある場合、またはそれらの線に沿って何か他のものを挿入する必要がある場合)、いつでもどこを変更できますか?インスタンス化されます (ただし、これが発生した場合、実際にはユーティリティ クラスがなくなり、このクラスがアーキテクチャにどのように適合するかを再検討する必要があるように思えます)。

于 2013-07-26T07:26:10.553 に答える
1

静的クラス具象クラスの違いと使用法を検討するときは、念頭に置いておくべき意味があることを確認してください。たとえば、テスト容易性を参照してください (ただし、後で示すように、これはまったく確実ではありません)。行う:

  • インスタンスクラスには状態があり、状態を管理し、動作はその内部状態に関連しています。操作が何らかの形で内部状態に関連していない場合、これらは真に静的メソッドの候補ですが、それについては後で詳しく説明します。これは カプセル化のベースでもあり、SRP (Single Responsibility Principle) と密接に関連しています。これは、クラスが 1 つのことを行うだけでそれ以上のことを行わないという単一の責任を持つべきであると述べているため、メソッドがすべて関連しているという事実が得られます。その内部状態に直接的または間接的に

  • 静的クラスは状態を管理しておらず、管理していません。たぶん、それはまったく真実ではないと言う人もいるかもしれません。シングルトンを参照してください。シングルトンは良いかもしれませんが、静的クラスとして設計されたシングルトンはアンチパターンに近すぎます。この場合、シングルトンは 1 つのインスタンスだけを管理することで、IoC コンテナーと同じように管理できます。必要に応じて、コンテナーの有無についていくつかの例を提供できます。

ええと、静的クラスはアンチパターンに近いものだと誰かが言います。たとえば、テスト容易性などです..まあ、これは真実ではありません。これは、静的クラスと関連するテストが何に関連しているかに依存します。偉大なソフトウェア アーキテクトであるUdi Dahanによる非常に良い例を報告します。たとえば、 Domain Eventsに関する優れた記事で、彼は静的クラスとテスト可能性について他のことについて話しています。ドメインイベントを発生させる方法とドメインイベントを使用したユニットテストのセクションに行くと、イベントの救済、彼はそれについて話します。

その後、あなたが言うように、2つの別の違いはメモリコストに関するものですが、他の人はそれについて言っています。Reshaper などのツールは、状態を処理しないインスタンス クラス/メソッドを静的表現に変換することを提案することに注意してください。これは、メモリと使用の利点です。

あなたのデザインについての最後の言葉:CommonDaoOperations状態を処理しない真に静的なクラスのように見えるので、それが行う仕事のために、それは静的なクラスになるための良い候補です。代わりに、IoC コンテナーを使用し、そのクラスを正しい方法で構成して、"シングルトン" として扱うことができます。コンテナーを使用せずに他の方法でそれを実現する方法はたくさんあります。 シングルトンと静的クラスC# Singleton, Static Classについて説明している簡単な記事です。確かに、ヘルパーを返すプロパティを作成することはあまり良い設計ではなく、get 操作の新しいインスタンスを返すプロパティは常に悪い設計です。それは確かな理由で正当化されます...

したがって、設計とヘルパー クラスの使用方法を確認すると、上記のリンクで Udi が言う言葉は、実装する必要があるソリューションをよく説明しています。

于 2013-07-26T09:17:15.927 に答える