アプリケーションの設計では、通常、オブジェクトをデータベース内の重要なテーブルにマップします。オブジェクトは、そのデータに関連するすべてのもの (リンク テーブルを含む) を処理します。たとえばActivity
、 と のようなプロパティ、 と のname
ようdue_date
なメソッド、および と のようなメソッドload()
を使用してsave()
、他のオブジェクト (の配列) を返すオブジェクトを作成しました。単一責任の原則に違反しているため、これは「悪い」OOP ですか?getParent()
getContributors()
getTeam()
5 に答える
それは状況とあなたが持っている正確なコードに依存します: あなたの設計は複数の責任に触れるかもしれませんが、それでもかなり良い OOP で保守可能です。
同様のコードで各クラスでload()
andを処理しますか? それとも、いくつかのクラスでこの機能に使用される他のオブジェクト内および他のオブジェクトにタスクを委任しますか? これは、SRP の半分であり、設計どおりです。save()
load()
save()
そうでない場合、あなたのコードは本当に少し臭いようです。それが複数の責任をカバーしているかどうかを確認するには、次のことを自問してください。あなたの状況では、少なくとも、上記の状況に到達するために、異なるクラス内および異なるクラス内の同様のコードをリファクタリングしようとします。load()
save()
- メンテナンス性が大幅に向上し、
- クライアントのコードを変更する必要はありません。
あなたが説明しているのは ActiveRecord であり、SRP に違反していることはよく知られています。また、ActiveRecord は、テーブルの行がオブジェクトと密接に一致する場合にのみうまく機能します。インピーダンスのミスマッチが大きくなりすぎると、後でシステムを変更するのが難しくなります。
これは必ずしも悪い OOP ではありませんが、永続化ロジックとドメイン ロジックが分離されていないため、技術的負債の一種です。SOLID 原則のいずれかに違反すると、通常、変更が困難なコード、壊れやすいコード、再利用できないコードにつながります。
それらの負債のいくつかは問題ではありません。それは、これらの負債が利子を蓄積するときです。たとえば、他の設計上の決定に波及し始めるときです。言い換えれば、システムを変更することがより困難になっていることに気づいたら、より保守しやすいソリューションにリファクタリングするなど、負債を返済するようにしてください。
うーん..この段階ではわかりにくいです。クラス全体をパスビンすることもできますが、..
はい、悪い OOP のようです。データベースおよびドメインロジックとのやり取りを担当する同じクラスがあります。これにより、クラスが変更される 2 つのまったく異なる理由が作成されます。
DataMapperパターンを調べると役立つ場合があります。
多分私はこれで暗闇の中を蹴るでしょう(私は専門家ではないので)しかし:
ドメイン オブジェクト内のメソッド load() および save() はActive Record (別の説明) と呼ばれます。これは悪いことではありません (私は嫌いですが)。なぜなら、あなたの後で、またはあなたと一緒に働く可能性のある人々は、それらのオブジェクトを永続化する方法を理解するのに苦労することが少なくなるからです。
その他の方法について。それがオブジェクト ドメインにあり、オブジェクトの動作を表している場合は、それほど悪くはありません。うまく設計されていれば、それは非常に良いものになる可能性があります。ドメイン駆動設計は貧血ドメイン モデルの反対である豊富なドメイン モデルの使用を奨励します。貧血ドメイン モデルには、プロパティと getter および setter のみを持つドメイン オブジェクトがあります。そのため、オブジェクトのドメイン内にある限り、追加のメソッドを配置することは悪いとは見なされません。
これは、私が読んだ本や記事からそれらの概念を理解している限りです..
それが役に立てば幸い..
モデルはロジックとデータベースの間の層だけであるべきだという考えをやめることが重要だと思います。モデルはデータベースや他のモデルと連携できます。すべてのロジックはモデル内にある必要があります。
次の 2 つの方法があると思います。
- モデルは
getContributors()
メソッドでIDの配列を返すことができ、これらのIDをオブジェクトに変換する新しいオブジェクト(おそらくFactory)を作成できます。 - モデルはオブジェクトの配列を返すことができますが、
new
キーワードを使用せずに、ファクトリまたは依存関係コンテナーを介して (私は DC を好みます)。