1

単一責任の原則と高/低凝集度の原則を理解していると思いますが、次の質問はまだ私にいくつかの混乱を引き起こしています

1)プロパティが任意に/ランダムにクラスに配置されると仮定Planetします(つまり、必要なコードがないか、これら2つのプロパティによって返される2つのオブジェクトを操作します)-言い換えると、プロパティはCarクラスに属していませんBirdCarCarPlanetBird

a)

SRPは、オブジェクトを変更する理由は1つだけであると述べています。

public class Car
{
    public void StartEngine()
    { ... }

    private Planet Planet
    {
        get { ... }
    }

    private Bird Bird
    {
        get { ... }
    }
}

クラスはCarSRPに違反していますか?変更PlanetやインスタンスがクラスBirdに伝播しないため、SRPが破損しないと思いますか?Car

b)

凝集度とは、クラス内でメソッドとクラスレベルの変数がどれだけ密接に関連しているかを指します。非常にまとまりのあるクラスでは、すべてのメソッドとクラスレベルの変数を一緒に使用して、特定のタスクを実行します。凝集度の低いクラスでは、関数がランダムにクラスに挿入され、さまざまな異なるタスクを実行するために使用されます

クラスにこれらの2つのランダムなプロパティが含まれていてもCar、1つの特定のタスク(またはいくつかの密接に関連するタスク)を実行するとします。

それでも特定のタスク(またはいくつかの密接に関連するタスク)を実行しているにもかかわらず、それは凝集Car度が 低いと言えますか?

2)とプロパティは、特定のタスクを実行するためにインスタンスのメソッドによって使用され、概念的には2つのプロパティが属していない場合でも、高い凝集度を持つPlanetと想定します(したがって、代わりにインスタンスが次のように渡された方がよいでしょう)それらを操作するaのメソッドへの引数)BirdCarCarCarPlanetBirdCar

ありがとうございました

HELTONBIKER:

1)

鳥と惑星を車の中にカプセル化したので(プライベートの場合はさらに悪いですが)、車のクラスには3つの変更理由があります。

Car 最初の質問ではCar'sメソッドが2つのプロパティでさえ機能せず、したがってパブリックAPIへの変更がクラスに影響を与えないPlanet'sため、 3つの理由がどのように変更されるのかわかりません。Bird'sCar

2)

The problem here has two components:
1.  Bird and Planet are contained (as opposed to aggregated) in Car class;
2.  Bird and Planet are not conceptually related to Car, much less by some containment relationship.

a)これは紛らわしいです:インスタンスが含まれているか集約されている かどうかに関係なく、インスタンスCarの変更のために変更する必要がある可能性は(少なくとも私の最初の質問では)まったく同じではありませんか?PlanetBirdPlanetBird

b)2番目の質問では、単一の特定のタスクCarを実行するために2つのプロパティを操作する方法があります。したがって、概念的には少なくともある程度関連しているのではないでしょうか。2番目の質問クラスでも、単一のタスクのみを実行している(そして、タスクを実行するために2つのプロパティを使用している) にもかかわらず、凝集度が低いと思いますか?

4

3 に答える 3

1

car クラスは、その一連の責任とはまったく異なるクラスを指すため、凝集度は低くなります。また、Planet と Bird は公開されているため、コンシューマーにこれらのプロパティへのアクセスを提供したため、カップリング サーフェスが高くなります。車はこれらを内部で使用します。

いずれにせよ、結合/結束の議論を無視して、Carが「惑星または鳥を取得する方法」の責任を負っているという理由だけで、SRPに違反しています.

于 2013-01-14T19:19:41.643 に答える
1

1) は と をCar保持できないPlanetと思いますBird。このように、Car には 2 つの異なる責任があります。それは、自動車の機能といくつかの奇妙なオブジェクトの保持です。ワールド内のオブジェクトを保持する他のオブジェクト/クラスが必要です: 例: クラスWorldContainer

2)あなたの例はどちらも凝集度が低いと思います。車といくつかの異なるオブジェクトの管理は、他のインターフェースを使用して行う必要があります。それらを接着するインターフェース。

于 2013-01-14T19:16:17.370 に答える
1

SRP は、クラスを変更する理由が 1 つだけであるべきであることを意味します。

したがって、Car クラスの変更は、Car の概念モデルが変更されたことを意味するはずです。

しかし、Bird と Planet を Car 内にカプセル化したため (プライベートな場合はさらに悪いことに)、 Car クラスには変更する 3 つの理由があります。

  1. 自動車の概念モデルおよび/または動作の変更。
  2. Bird の概念モデルおよび/または動作の変更。
  3. Planet の概念モデルおよび/または動作の変更。

ここでの問題には、次の 2 つのコンポーネントがあります。

  1. Bird と Planet は (集約ではなく) Car クラスに含まれます。
  2. Bird と Planet は概念的に Car とは関係がなく、ましてやなんらかの包含関係ではありません。

または、率直に言って (教訓的な演習としてそうしていただければ幸いです)、示されているアーキテクチャは単に意味を成しません。


集計の例 (Python)。非結合クラスは、それらを参照する Car クラス定義の外で定義されます。Car は Bird と Planet に依存していますが、現在 Bird と Planet は単独で存在しています。

class Bird():
    hasWings = True

class Planet():
    isFlat = False

class Car():
    owner = Bird()
    substrate = Planet()

パラメータ渡しの例 (車のクラスのみ。他のクラスは上記と同様であると仮定します)。現在、Car コンストラクター ( __init__Python のメソッド) はインスタンスをパラメーターとして受け取ります。これは、好ましい場合とそうでない場合があります。依存関係と結合は残っていますが、おそらくより具体的なものになりました。

class Car():
    def __init__(bird, planet)
        owner = bird
        substrate = planet

結局、この結束と結合の問題全体は、ソフトウェア自体とはあまり関係がなく、開発者と関係があります。コンパイラは、名前空間、プロジェクト フォルダ、およびファイルの配布が「コンパイル」される限り、乱雑であっても気にしません。しかし、あなたがしたように(BirdとPlanetクラスをCarクラスの中に入れて)何の意味もありません。まず始めに、各クラスのバージョン管理は非常に混乱します。

ですから、犯してはいけない純潔は、そのために本に書かれているわけではありません。この純粋さは、人間が機械命令と格闘することから得られた (またはそうあるべきだった) ものです。オブジェクト指向、および一般的なソフトウェア アーキテクチャは、マシン向けではなく、開発者 (の一部) の心向けです。

于 2013-01-14T19:53:12.717 に答える