5

私が書いているアプリケーションには、ユーザーのグループがあります。これをコミュニティと呼びましょう。各コミュニティには、いくつかのオブジェクト (出席者、目的、タスク、成果など) が関連付けられている会議があります。

親が作成されたときに子オブジェクトの初期化を実装する最良の方法は何かについて、少し混乱しています。ここでは、単純化されたクラスのセットアップを示します。

最初の実装

<?php
class community
{
     public $id;
     public $name;
     //Store an array of meeting objects
     public $meetings = array();
     //Store an array of member objects
     public $members  = array();
     //etc

     public function getProperties()
     {
         //hit database for community properties including ids of meetings 
         //and members associated with this community
         //Set community properties

         //Use returned ids to populate community properties
         foreach($returnedMeetingIds as $meetingId)
         {
              //The meeting class is responsible for its own init.
              $newMeeting = new Meeting();
              $newMeeting->id = $meetingId;
              $newMeeting->getProperties();
              $this->meetings[$meetingId] = $newMeeting;
         } 
     }
}
?>

このメソッドは、各オブジェクトに初期化の責任を負わせます。私の意見では、保守性とモジュール性に優れていますが、各会議の子オブジェクトも初期化を担当するため、会議が追加されるにつれて、これが大きなカスケード ボトルネックになることがわかります。

これを行うために考えられるもう 1 つの方法は、1 回のデータベース呼び出しで $meetings 配列を設定することです。すべてのミーティングは、コミュニティ ID フィールドを持つ 1 つのテーブルに保存されます。

2 回目の実装

<?php
class community
{
     public $id;
     public $name;
     //Store an array of meeting objects
     public $meetings = array();
     //Store an array of member objects
     public $members  = array();
     //etc

     public function getProperties()
     {
         $sql = 'SELECT * 
                 FROM meetings
                 WHERE community_id = :community'
         //etc
         $stmt->execute();
         while($meeting = $stmt->fetch())
         {
              $newMeeting = new Meeting();
              $newMeeting->id = $meeting['id'];
              //etc
              $this->meetings[$newMeeting->id] = $newMeeting;
         }

     }
}
?>

2 番目のクラスの方がはるかに高速に実行されると思いますが、ミーティング クラスをコミュニティ クラスに結合したので、これは最善の解決策ではないように感じます。

私の質問は、これらのクラスのグループ (コミュニティ、会議、目的、成果、タスクなど) を切り離すために、どれだけの在庫を配置する必要があるかということです。私自身の個人的な感覚では、トラフィック負荷に対して不適切であることが判明するまで最初の実装を使用し、その後2 番目の実装のようなものに移行する必要があります。もう少し経験のある人がベストプラクティスであるとわかったものを知りたいです。これはうさぎの穴だと思います。一度ダウンすると、後でリファクタリングするのが難しくなる可能性があります。また、どちらの方法もこれにアプローチする正しい方法であるとは確信していません。提供されたヘルプに感謝します!

4

1 に答える 1

2

コミュニティでこれらすべての会議が本当に必要かどうかを自問する必要があります。次の使用例を見てみましょう。

  1. 会議のリストを含むコミュニティのすべての情報を出力したいと考えています。これは、コミュニティとそのすべてのミーティングを構築したい場合に有効なケースのように思えるかもしれません。しかし、これにはもっと効率的な方法があります。

    class Controller {
    
        public function showCommunity($id) {
            $community = $this->communityGateway->findCommunity($id);
            $meetings = $this->meetingGateway->findMeetings($community->getCommunityId());
    
            // output your community information and meeting information
        }
    }
    
  2. コミュニティのすべての会議を操作する必要があるユース ケースがあります。あなたのアプローチでは、次のようにします:

    $community = new Community();
    $community->doSomethingToAllMeetings();
    

    しかし、これには例 1 のアプローチを使用することもできます。出力する代わりに、操作に必要なアクションを実行します。


ただし、会議が必要な場合は、コミュニティの外でそれらを作成し、依存関係としてコミュニティ オブジェクトに渡す必要があります (作成時に必要な場合はコントローラーで、後で追加される場合はセッターとして)。

class Community {

    public function __construct($meetings) {
    ...
    }
}

上記のアプローチから何が得られますか?

  • 各コミュニティのすべての会議情報を常にロードするとは限りません。
  • クラスを分離します。一方は他方なしで存在できるようになり、テスト用に置き換えることができます。
  • オブジェクトの作成によってビジネス ロジックに過度の負担がかかることはありません。これは、ビジネス オブジェクトではなく、コントローラー レベルで発生するはずです。
  • 必要に応じて、これらのゲートウェイを置き換えて、別の場所からデータをロードすることもできます。
于 2012-10-15T16:16:39.100 に答える