この記事では、データクラスは「コード臭」であると主張しています。理由:
新しく作成されたクラスに含まれるパブリックフィールドが少数(そしておそらく少数のゲッター/セッターさえ)である場合、これは通常のことです。しかし、オブジェクトの真の力は、データに動作タイプまたは操作を含めることができることです。
オブジェクトにデータのみが含まれているのはなぜ間違っているのですか?クラスの中心的な責任がデータを表すことである場合、データを操作するメソッドを追加して単一責任原則を破らないでしょうか?
この記事では、データクラスは「コード臭」であると主張しています。理由:
新しく作成されたクラスに含まれるパブリックフィールドが少数(そしておそらく少数のゲッター/セッターさえ)である場合、これは通常のことです。しかし、オブジェクトの真の力は、データに動作タイプまたは操作を含めることができることです。
オブジェクトにデータのみが含まれているのはなぜ間違っているのですか?クラスの中心的な責任がデータを表すことである場合、データを操作するメソッドを追加して単一責任原則を破らないでしょうか?
回答:
純粋なデータオブジェクトを持つことには、まったく問題はありません。作品の作者は率直に言って、彼が何について話しているのか分からない。
このような考え方は、「真のオブジェクト指向」がプログラミングの最良の方法であり、「真のオブジェクト指向」はすべてデータと機能が混在する「リッチデータモデル」に関する古い失敗したアイデアに由来します。
現実は、特にマルチスレッドソリューションのこの世界では、実際には逆のことが当てはまることを示しています。不変のデータオブジェクトと組み合わせた純粋な関数は、明らかにコード化するためのより良い方法です。
純粋なデータオブジェクトを持つことには、まったく問題はありません。著者は、私が知っているソフトウェア開発者と共有していない意見を持っています。
特にデータベースマッピングでは、一般に、データベースに格納されたフィールドとゲッターとセッターのみを含むエンティティクラスがあります。ウィキペディアHibernate(フレームワーク)
多くのツール/フレームワークで使用されるJava Beanの穴のアイデアは、フィールドと関連するゲッターとセッターのみを含むBeanと呼ばれるデータクラスに基づいています。Wikipdia JavaBeans
ファジット:
誰かが何かが「悪い」または「コードのにおい」であると主張する場合、あなたは常に与えられた理由を探すべきです。理由が納得できない場合は、他の誰かにもっと良い理由や別の意見を求めてください。(このフォーラムでやったように)
マーティン・ファウラーによる正当な理由:
「Tell-Don't-Ask」は、オブジェクト指向とは、データを操作する機能とデータを結び付けることであることを人々が思い出すのに役立つ原則です。代わりに、オブジェクトに何をすべきかを伝える必要があります。これにより、データに合わせて動作をオブジェクトに移動することが推奨されます。
baz
、それを行うには、最初にオブジェクトを要求する必要があります。おそらくメソッドがプライマリであるプログラミングパラダイム(関数型プログラミングなど)ではこれは理にかなっていますが、オブジェクト指向環境ではオブジェクトはプライマリであり、それに作用するデータと関数の両方を含む必要があるため、絶対に意味がありません。オブジェクトからメソッドを削除するとカプセル化が増加するという主張も、私が知る限りではまったく逆ですbaz
。これは、オブジェクトの外側に現れていることを意味しているためです。
理解する必要があるのは、2種類のオブジェクトがあるということです。
動作するオブジェクト。これらは、ほとんど/すべてのデータメンバーへのパブリックアクセスを許可しないでください。これらに対して定義されているアクセサメソッドはごくわずかです。
例はコンパイルされた正規表現です:オブジェクトは特定の動作を提供するために作成されます(特定の正規表現と文字列を一致させ、(部分的な)一致を報告します)が、コンパイルされた正規表現がどのように動作するかはユーザーのビジネス。
私が書くほとんどのクラスはこのカテゴリに属します。
実際には単なるデータであるオブジェクト。これらは、すべてのメンバーをパブリックに宣言するだけです(または、アクセサーの完全なセットを提供します)。
例はクラスPoint2D
です。このクラスのメンバーに確保する必要のある不変条件はまったくありません。また、ユーザーはとを介してデータにアクセスできる必要がmyPoint.x
ありmyPoint.y
ます。
個人的に、私はそのようなクラスをあまり使用しませんが、どこかにそのようなクラスを使用しない、私が書いたコードの大きな部分はないと思います。
オブジェクト指向に習熟することには、この区別が存在することを理解し、クラスの機能をこれら2つのカテゴリのいずれかに分類することを学ぶことが含まれます。
C ++でコーディングする場合class
、オブジェクトの最初のカテゴリとstruct
2番目のカテゴリに使用することで、この区別を明確にすることができます。もちろん、この2つは同等class
ですが、デフォルトではすべてのメンバーがプライベートであり、デフォルトではstruct
すべてのメンバーがパブリックであると宣言されます。まさにあなたが伝えたい情報の種類です。