0

関心の分離または単一責任の原則

質問のドロップダウン リストにある「既に回答が得られている可能性がある」質問の大部分は、「理論」を説明しているだけであり、私の単純な質問に答える具体的な例ではありません。

私が達成しようとしていること

"guestbook" という名前のデータベース テーブルにあるプロパティにマップする GuestbookEntry という名前のクラスがあります。とても簡単です!

もともと、データベースにエントリを持つすべての GuestbookEntry オブジェクトの配列を取得する getActiveEntries() という名前の静的メソッドがありました。次に、php クラスを適切に設計する方法を学びながら、次の 2 つのことを学びました。

  1. 静的メソッドは望ましくありません。
  2. 関心事の分離

私の質問:

関心の分離に対処する場合、GuestbookEntry クラスが単一のゲストブック エントリの管理のみを担当する場合、この getActiveEntries() メソッドはどこに移動する必要がありますか? これを行うための絶対的な適切な方法を学びたいです。

4

3 に答える 3

1

質問には実際には2つの項目があると思います。

  1. @duskwuff が指摘しているように、静的メソッド自体には何の問題もありません。それらの注意点 (「Late Static Binding」など) と制限を知っている場合、それらは使用するツールの 1 つにすぎません。ただし、DB との対話をモデル化する方法は、関心の分離や単体テストなどに影響を与えます。

  2. さまざまな理由から、永続化を行う「絶対に適切な方法」はありません。その理由の 1 つは、それに取り組む方法ごとに異なるトレードオフがあることです。どちらがプロジェクトに適しているかを判断するのは困難です。もう 1 つの重要な理由は、言語が進化するため、新しい言語機能によってフレームワークが物事を処理する方法が改善される可能性があることです。したがって、それを行う完璧な方法を探す代わりに、リレーショナル データベースを使用することを前提として、オブジェクト指向の永続性にアプローチするさまざまな方法を検討することをお勧めします。

    • Active Recordパターンを使用します。ここまでの作業はアクティブ レコード スタイルのように見えるので、当然のことと思われるかもしれません。アクティブなレコードには、把握しやすいという利点がありますが、DB と密接に結合する傾向があります (もちろん、これは実装に依存します)。これは、懸念事項の分離の観点からは好ましくなく、テストが複雑になる可能性があります。
    • ORM ( DoctrinePropelなど) を使用します。この場合、骨の折れる作業のほとんどはフレームワーク (BD マッピング、外部キー、カスケード削除、いくつかの標準クエリなど) によって行われますが、フレームワークのルールに適応する必要があります (たとえば、 Doctrine 1 がプロジェクト内の階層を処理した方法. 私の知る限り、このことは Doctrine 2 で解決されます)。
    • プロジェクトのニーズとプログラミング スタイルに合わせて独自のフレームワークを展開します。これは明らかに時間のかかる作業ですが、多くのことを学びます。

一般的な経験則として、主に単体テストのために、ドメイン モデルを DB などからできるだけ独立させようとしています。単体テストは、プログラミング中は常に実行されている必要があるため、高速に実行する必要があります (プログラミング中は常にターミナルを開いたままにし、変更を適用した後にスイート全体を実行するために常にターミナルに切り替えています)。DB と対話する必要がある場合、テストは遅くなります (中規模のシステムには 100 または 200 のテスト メソッドがあるため、メソッドをミリ秒単位で実行する必要があります)。

最後に、DB と通信するオブジェクト (モック オブジェクトなど) に対処するためのさまざまな手法がありますが、ドメイン モデルと DB の間に常にレイヤーを配置することをお勧めします。これにより、モデルが変更に対してより柔軟になり、テストが容易になります。

編集: @MikeSWの回答にも記載されているDAOアプローチについて言及するのを忘れていました。

HTH

于 2012-10-31T14:13:01.163 に答える
0

自分自身を推測するのはやめましょう。静的メソッドgetActiveEntries()は、この問題を解決する完全に合理的な方法です。

あなたが探している「エンタープライズ」ソリューションには、GuestbookEntryFactory オブジェクトを作成し、アクティブなエントリを取得するように構成し、それを実行するという行に沿った何かが含まれる可能性があります。これはばかげています。静的メソッドはツールであり、これは完全に適切な仕事です。

于 2012-10-31T04:44:48.467 に答える
0

GetActiveEntries は、GuestBookEntry の配列を返すリポジトリ/DAO のメソッドである必要があります。もちろん、そのリポジトリはインターフェイスを実装できるため、ここでは簡単にテストできます。

これは明らかに永続アクセスの問題であるため、これに静的メソッドを使用することに同意しません。GuestBookEntry は「ビジネス」機能のみを考慮し、db は考慮しないでください。そのため、リポジトリを使用すると便利です。そのオブジェクトは、ビジネス層を db 層にブリッジします。

私のphpのさびたを編集しますが、あなたはアイデアを得る.

public interface IRetrieveEntries
{
    function GetActiveEntries();
}

public class EntriesRepository implements IRetrieveEntries
{
    private $_db;
    function __constructor($db)
    {
       $this->_db=$db;
     }

    function GetActiveEntries()
    {
      /* use $db to retreive the actual entries
       You can use an ORM, PDO whatever you want 
         */
      //return entries;
    }

  }

機能にアクセスする必要があるすべての場所にインターフェイスを渡します。つまり、コードを実際のリポジトリに結合しません。単体テストにも使用します。ポイントは、GetActiveEntries メソッドで実際のデータ アクセスをカプセル化することです。アプリの残りの部分はデータベースについて認識しません。

リポジトリ パターンについては、私が書いたいくつかのチュートリアルを読むことができます (使用されている C# は無視してください。概念はどの言語でも有効です)。

于 2012-10-31T08:21:17.513 に答える