質問

複数の PHP フレームワーク、特に Zend Framework について調べていますが、今後の適切な方法について混乱しています。

Zend Framework は ActiveRecords を使用せず、代わりにテーブル データ ゲートウェイと行データ ゲートウェイ パターンを使用し、DataMapper を使用して行データ ゲートウェイの内容をモデルにマップします。これは、モデルに 1 がない場合に ActiveRecord が機能しないためです。 1 データベーステーブルへのマッピング。があります この例 Zend クイックスタート ガイドを参照してください。

私にとって、彼らの例は、大量のゲッターとセッターがあちこちにあり、非常に肥大化しているように見えます。ドメイン駆動設計に関するさまざまなブログ投稿を見つけました。これは、多くのゲッターとセッターを使用すると内部モデル データがすべて外部に公開されるため、パブリック属性よりも利点がないため悪い習慣であると主張しています。 ここに一例を示します.

私の質問:これらのゲッターとセッターを削除した場合、ビューはどのようにレンダリングされますか?実際にユーザーに何かを表示できるように、ある時点でデータがビューにヒットする必要があります。DDD のアドバイスに従うと、MVC における M と V の分離が解消されるようです。MVC と Zend の例に従うと DDD が壊れるようで、すべてのモデルに対して大量のゲッター、セッター、DataMapper を入力することになります。大変な作業であるだけでなく、DRY にも違反しているようです。

いくつかの良い例 (へのリンク) や、すべてがどのように組み合わされるかについての詳細情報をいただければ幸いです。ここで建築と設計のスキルを向上させようとしています。

役に立ちましたか?

解決

値オブジェクトを使用すると、これらのパブリックセッターメソッドの一部を削除できます。 違いの説明エンティティと値オブジェクトの間。値オブジェクトは不変であり、多くの場合エンティティに関連付けられています。コンストラクタですべての値を渡す場合、これらのプロパティを外部コードから設定する必要はありません。

余分なもので、回答に直接関連するものではなく、DDDに焦点を当てたもの:

(免責事項:Zend Frameworkについて知っている唯一のことは、リンクされた記事で読んだことです。)Zend Frameworkは、リポジトリの代わりにDataMappersを使用しています。これは本当にDDDっぽいですか?まあ、 Fowlerのリポジトリの解釈はノーと言うかもしれません。ただし、Eric Evans氏は、DDDリポジトリは非常にシンプルにできると述べています。最も単純な場合、リポジトリはDataMapperです(DDDブックを参照)。さらに複雑でまだDDDについては、Fowlerの記事を参照してください。 DDDには、パターン定義とは異なる概念的なリポジトリがあります。

ドメイン駆動設計について読み続けることをお勧めします。ゲッターとセッターがDDDに違反しているという仮定には欠陥があると思います。 DDDは、ドメインモデルとそれを実現するためのベストプラクティスに焦点を合わせています。アクセサはほんの一部です。

他のヒント

すべてのゲッター/セッターを実装する必要はありません。use__get()および__set()を使用できます。問題は何ですか?

この記事を読んだことから、質問は実用的というより哲学的です。

詳しく書く時間はありませんが、2セントです。クラスは内部を隠す必要があるため、getおよびsetリクエストの数を制限したいことに同意しますが、JavaとPHPは異なるツールであり、目的も異なることを考慮する必要があります。 Web環境では、リクエストごとにクラスが構築および削除されるため、作成するコードは巨大なクラスに依存するべきではありません。あなたが指摘した記事で、著者はクラスにビューロジックを配置することを提案しています。おそらく複数の形式(rss、htmlなど)でビューを表示したいので、これはおそらくWebでは意味がありません。したがって、アクセサーメソッド(get& set)を使用することは必要な悪です。あなたはまだあなたが足で自分自身を撃たないように思慮深くそれらを使いたいです。重要なのは、クラスに外部での作業を強制するのではなく、クラスに作業を行わせることです。直接ではなくメソッドを使用してプロパティにアクセスすることにより、必要な内部を非表示にします。

繰り返しますが、この投稿ではいくつかの例を使用できますが、今は時間がありません。

他の誰かが、アクセサメソッドが悪ではない理由のいくつかの例を提供できますか?

ここには 2 つのアプローチがあります。私が「尋ねないで伝えるアプローチ」と呼ぶものと、もう 1 つは ViewModel/DTO アプローチです。基本的に、質問はあなたの見解における「モデル」が何であるかを中心に展開します。「尋ねないでください」では、オブジェクトを外部化できる唯一の方法はオブジェクト自体からであることが要求されます。つまり、オブジェクトをレンダリングするには、render メソッドが必要ですが、その render メソッドはインターフェイスと通信する必要があります。このようなもの:

class DomainObject {
   ....
   public function render(DomainObjectRenderer $renderer) {
        return $renderer->renderDomainObject(array $thegorydetails);
   }
}

Zend Framework のコンテキストでは、Zend_View をサブクラス化し、そのサブクラスにこのインターフェイスを実装させることができます。

以前にもこれをやったことがありますが、少し扱いに​​くいです。

2 番目のオプションは、ドメイン モデルを ViewModel オブジェクトに変換することです。これは、データを単純化して平坦化し、「文字列化した」ビューのようなもので、特定のビューごとにカスタマイズされ (ビューごとに 1 つの ViewModel があり)、その途中で元に戻ります。 、POST データを EditModel に変換します。

これは ASP.NET MVC の世界で非常に一般的なパターンですが、アプリケーションの「レイヤー」間でデータを転送するために使用されるクラス「DTO」パターンにも似ています。面倒な作業を行うにはマッパーを作成する必要があります (実際には DataMapper と変わりません)。PHP 5.3 では、リフレクションを使用してプライベート プロパティを変更できるため、DomainObject 自体を公開する必要さえありません。

ゲッターとセッターの実装には、私の目には2つの利点があります:

  1. 公開するプロパティを選択できるため、必ずしもモデルの内部をすべて公開する必要はありません
  2. オートコンプリートを備えたIDEを使用する場合、「get」と入力し始めると、利用可能なすべてのプロパティがTABでなくなります。または「設定」—これだけで十分です。
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top