純粋なPOCOモデルを持つことの利点は何ですか?


14

純粋なPOCOモデルを持つことの主な利点は何ですか?私は、モデルはクリーンでシンプルであるべきだと思いますが、モデルクラス内の子オブジェクトのメンテナンスを維持する傾向があります。例えば、私が持っている場合ClassAClassB、以下のように定義されました:

public class ClassA
{
    public string MyProp { get; set; }
    public IEnumerable<ClassB> Children { get; }

    public void AddChild(ClassB newChild) { /*... */ }
    public void RemoveChild(ClassB child) { /* ... */ }
}

public class ClassB
{
    public string SomeProp { get; set; }
} 

addメソッドとremoveメソッドがあることに本質的に問題はありますか?代わりにリストを公開し、クライアントコードに、null以外の単純なデータ検証の責任を渡すものを追加できるようにし、別のクラスに複製しないようにする必要がありますか?

どんな助けもありがたいです。ありがとう。


null ClassB引数をオブジェクトのNullObjectパターンバージョンに変換するなど、何らかの値を追加しない限り、Add / Removeメソッドを削除します。– AddChild(ClassB newChild) => Children.Add(newChild ?? new NullClassB())
Graham

ActiveRecordクラスの頭痛の種を何百ものメソッドで処理したことがあるなら、いつでも欲しいものであるかもしれないし、そうでないかもしれません。
ケーシー

この特定の設計を回避する主な理由は、.net設計ガイドラインに違反するためです。それは完全にarbitrary意的ですが、人々はコレクションに変化するメソッドがあることを期待しています。
フランクヒルマン

@Casey Active Recordパターンを使用していません。addメソッドは単純にマイナーデータの検証を行っています。コレクションが公開されておらず、内部リストに追加および削除するだけなので、removeメソッドがあります。ただし、組み込みの追加/削除メソッドを使用しながら検証を実行できる別のコレクションタイプを使用するように変更しました。
ジェシー

回答:


42

2つの質問は無関係です。

純粋なPOCOモデルを持つことの利点は何ですか?

純粋なPOCOは、エンタープライズフレームワーク、慣例、[]に依存せず、同様に依存するオブジェクトに密接に接続されていません。言い換えれば、世界はPOCOを中心に完全に変化することができ、世話をせずにそれを行うだけです。フレームワークを更新したり、新しいシステムに移動したり、おかしな見方をして、それを破ることはできません。ただ動き続けます。唯一の依存関係は、明示的に要求するものです。

POCOはPOJOのアイデアに他なりません。JがCに変更されたのは、Javaの名前にC#を使用している場合、その名前にJavaを含む概念を説明するときに人々があなたを面白そうに見ているからです。アイデアは言語に依存しません。彼らは単純にそれを「Plain Old Objects」と呼ぶこともできました。しかし、誰がPOOの使用について自慢したいのでしょうか?

私はファウラーにその起源を説明させます:

この用語は、Rebecca Parsons、Josh MacKenzie、および私が2000年9月の会議で講演の準備をしている間に作られました。私たちは、なぜ人々がシステムで通常のオブジェクトを使用することに反対したのか疑問に思い、単純なオブジェクトには派手な名前がなかったためだと結論付けました。だから私たちは彼らに1つを与えました、そしてそれは非常にうまくいきました。

martinfowler.com:POJO

あなたの他の質問に関して:

addメソッドとremoveメソッドがあることに本質的に問題はありますか?

A直接知りたくないB。しかし、それはPOJOの問題ではなく、DIPの問題です。


私はB単純化のために直接依存していました。理想的には、これらは両方ともインターフェースを実装するでしょう。しかし、AまだのリストがありIInterfaceBます。AddChild子がインターフェイス参照を介して疎結合されている場合、メソッドに何か問題がありますか?
ジェシー

6
簡単にするために、私は馬鹿げたことをたくさんやることができます。私が嫌いなのは、AがBを知っていることです。AはBを使用しないので、Bと通信するために適切なA所有のインターフェースを定義する必要はありません。私が知る限り、Aはコレクションです。したがって、Aは<T>を介してBを処理する必要があるので、B についてそれを知る必要はありません。
candied_orange

2
また、頭字語での言語指定子の種類を避けるために、「プレーンな古いデータオブジェクト」の「PODO」を見ました。PODOは少し馬鹿げているように聞こえます(私にとっては、Tatooineで聞こえるような言い回しのような音です)。
KRyan

2
ファウラーのプレゼンテーションがPOOと呼ばれていたら、どれだけうまくいったのだろうか?
オリバー

3

追加と削除では、Collection<T>機能を実装しています。なぜIEnumerable<T>List<T>または他の可変クラスの代わりに使用しているのかを自問してください。どうやらそれはあなたのコレクションが読み取り専用であるべきだからではありません。

私が考えることができる唯一の理由は、公開したいアクセス方法を制御したいということです。その場合、独自のコレクションクラスを作成し、リストをカプセル化し、選択メソッドAddおよびRemoveを実装し、実装する方がよいでしょうIEnumerable<T>。次にIEnumerable<T>、子コレクションのタイプの代わりにそれを使用します。

しかし、私にList<ClassB>はおそらくあなたに役立つでしょう。


0

何をAddChild追加、RemoveChild削除しますか?データベース(または任意の種類の永続ストア)からのものである場合、Active Recordを取得しています。必ずしも悪いこととは限りませんが、@ CandiedOrangeが言及しているように、フレームワーク、規約、依存関係などを心配する必要があります。

同時に、それらがすべて同じアプリケーション内にある場合、ClassAからClassB(または少なくともInterfaceB)への依存関係を回避するポイントは何でしょうか?アプリケーションがモデリングしている現実の領域では、物事は互いに依存しています。実世界のオブジェクトに、それらに「属する」他のオブジェクトのコレクションがあります。コードでそれらの関係を表すことは完全に適切です。

少し複雑になるのは、ClassBがClassAとどのように関連付けられ、関連付けが解除されるかを正確に管理する必要があるようだからです。そのため、実装する動作が少しあります。クラス内に実装するか(完全に「合法」です。https://stackoverflow.com/a/725365/44586を参照)、またはその動作を含むある種の別個のクラスを使用できます。あなたの個々の状況にとって最も意味のあることをしてください。

いずれにせよ、POJO / POCOは、装飾されておらず、邪魔されないように意図されていたため、実際には単なるOOPです。OOPの原則に従うと、安全になります。


実際、AddChildは単に重複をチェックし、nullであり、どちらも許可していません。RemoveChildは、バックドアの追加を防ぐためにコレクションがIEnumerableとして公開されるために存在します。ただし、コレクションからの標準的な削除のみを実行します。
ジェシー

1
説明してくれてありがとう。ええ、それはPOCOにあるべき振る舞いのタイプとまったく同じように聞こえます。
ジョンMガント

Active Recordは単なる悪いパターンだと思います。
ケーシー

1
@Casey、あなたはそれについて私から議論を得ることはありません。しかし、誰かがそれを使用したいかどうかは議論しません。要点は、Jesseが永続性とモデル定義を統合するActive Recordのようなパターンを使用するつもりだった場合、CandiedOrangeが強調するすべての問題を抱えることになり、POCOとしての資格はありません。しかし、それは彼がとにかくやっていることではありません。
ジョンMガント
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.