2009-05-31 7 views
2

私は、集約と合成を使用してシミュレーション用のエンティティを作成しています。以下のC++の例でクラスの集約/合成メンバー間の関係を管理する

:上記の例で

class CCar 
{ 
    CCar(CDriver* pDriver) 
    { m_pDriver = pDriver; } 

    CDriver* m_pDriver; 

    CEngine m_Engine; 

    CDriverControls m_Controls; 
}; 

は、車は、エンジンと(組成物による)駆動コントロールのセットから成ります。車にはドライバーが必要です(アグリゲーションによる)。

しかし、これは階層的関係についてのみ説明します。ドライバーは車に属し、エンジンとコントロールは車にも属します。しかし、これらのメンバーはすべて互いに関連しています。ドライバーはコントロールでアクションを実行する必要があり、コントロールはエンジンでアクションを実行する必要があります。これらの関係は、複数の方向でも機能します。エンジンがストールしてコントロールが握られる可能性があります。または、コントロールが乱暴に回転してドライバーを傷つける可能性がありますか?そして、もしドライバーがエンジンの音を気に入らず車を離れるなら、どうでしょうか?これらの関係はどのように機能しますか?

私は他のオブジェクトと頻繁にやり取りする多くの異なるオブジェクトから多くの異なるエンティティを合成しており、これらの関係を設計された方法で管理する方法に興味があります。

よろしくお願いします。

編集:応答が示唆として

、これを管理するための一つの方法は、これは理にかなっていると、この具体的な例を解きなど、ドライバーに車を指し、そして車に運転手のポインタを与えています。しかし、設計上の意味では、これは運転者の責任を増加させます。このオブジェクトには、それがどの車に属しているかを把握することが任されていますが、確かにこれはどの物体が一緒に属しているかを把握するコンテナの義務です。同様に、これらの関係を管理してCCarを処理すると、CCarがblobに変わります。これらの種類の関係に対処するための設計されたソリューションはありますか?

答えて

1

これらを各クラスのメソッドに組み込みます。あなたが記述しているのは、各クラスの動作です。あなたの要件は、関係が双方向であることを示唆しています。 Controlsクラスには、Engineパラメータを取得してそのメソッドを呼び出すメソッドがあります。エンジンには、コントロールによって操作されるRPM、HP、トルクなどに限界があります(たとえば、「RPMがあまりにも低くなった場合、ストールアウト」など)。

これは単なる構図ではありません。ビルドの振る舞いとメソッドへのルール。これらのメソッドは、必要なものを表すパラメータを取ることがあります。

0

あなたは、おそらく車とドライバーの間で双方向の関連付けをしたい:

CCar(CDriver* pDriver) : 
    m_pDriver(pDriver) 
{ 
    m_pDriver->SetCar(this); 
} 

そして、ドライバーが車のパブリックインターフェイスを介してカーのメンバーにアクセスすることができます。

1

質問は「私のアプリケーションはこの関係を必要としますか?たとえば、シンプルな運転ゲームのために車のステアリングをモデリングする場合、おそらくサンルーフのモーターについて心配する必要はありません。ハンドルは車輪に接続されていることを知る必要がありますが、逆の関係は必要ありません。

ボトムライン - 実際の世界ではすべてが接続されていますが、コンピュータモデルでは特定の問題を解決するためにその世界を作りますが、そうではありません。

+0

返信ありがとうございます。 与えられた例は本当に単なる例ですが(おそらくより良いものを使用している可能性もありますが)、私は直面している問題を説明しようとしていました。私は実際に車とドライバーに関するプログラムを書いているわけではありません。 –

1

構成、集約、または継承ではなく、インターフェイスを強調することが有用な場合があります。たとえば、ドライバークラスは "ステアリングホイール"インターフェースを使用できるように記述することができます。もちろん、ステアリングホイールの実装は、「ステアリングホイール」インターフェイスの実装を提供します。同様に、かごは、ステアリングインプリメンテーションが利用されるように書かれた「カーインターフェース」を供給する。

あなたの実装では、合成、集約、および継承を使用することがあります。しかし、このアプローチでは、デザインを推進するのは本当にインターフェイスです。特定のインスタンスで合成、集約、または継承を使用するかどうかは実装の詳細に過ぎません。

+0

よかったですが、これは私にとってこれを解決するための素晴らしいスタートです。 –

0

この問題を解決するには、まず各コンポーネントの機能を確立することが重要です。

CCar - コンポーネントと集約を保持するコンテナです。

CDriver - ドライバ

CEngine表すオブジェクト - ドライバが与えられる小型でシンプルなプログラムの場合等

をエンジンを表すオブジェクト

を、簡略化設計を使用すべきCCARは新しいコンポーネントアドインを必要とするかもしれない場合、これは許容できない大規模なアプリケーションのために車へのポインタ

運転手がステアリングホイールだけでなく、車の色などを意図的に変更することができます。

ドライバは必要なビットにアクセスできますか?

m_pDriver->SetSteeringWheel(m_SteeringWheel); 
m_pDriver->SetHandBrake(m_HandBrake); 

この問題を解決しました。これで、ドライバは車に他の属性(色など)を使用できなくなりました。ただし、CDriverクラスにはより多くの責任が与えられます。 CDriverがたくさんのコントロールを使用することができる場所では、クラスが非常に大きくなり、これらのステアリングやハンドブレーキオブジェクトを操作する責任があります。運転手が他の車と同じコントロールを持っていない別のタイプの車に乗るとどうなりますか?今では、運転手は車両の操作方法を把握していなければなりません。余分なロジック。余分なブロブ。

このすべてを解決するには、メディエータークラス(またはバリアント)を使用して、ドライバーと車両とのやり取りを制御します。これは2つの方法のうちの1つで行うことができます。運転手は車にどのように対話するかを制御する車の調停者を持つことができます。あるいは、ドライバーは、対処しなければならない自動車の各コンポーネントまたは集合体のメディエーターを持つことができます。メディエータはさまざまな種類の車に再利用できるため、これはおそらくより良い解決策です。メディエータは、コンポーネント間の双方向関係を処理できる必要があります。

コンテナであるCCarは、メディエータのメンテナンス、つまりコンポーネント間の関係を維持する責任があります。それはちょうどそれがすべきである方法。

メディエータは、コンポーネント間のこの関係を処理します。

class CMediatorDriverToSteeringWheel 
{ 
CMediatorDriverToSteeringWheel(CDriver* pDriver, CSteeringWheel* pSteeringWheel) 
{ 
m_pDriver = pDriver; 
m_pSteeringWheel = pSteeringWheel; 
m_pDriver->AddMediator(this); 
m_pSteeringWheel->AddMediator(this); 
} 
}; 

... 

CCar::CCar(CDriver* pDriver) 
{ 
m_pDriver = pDriver; 
new CMediatorDriverToSteeringWheel(m_pDriver, &m_SteeringWheel); 
new CMediatorDriverToHandbrake(m_pDriver, &m_HandBrake); 
} 
+0

他のすべての答えのおかげで、皆私は私の質問について考える助けになった素晴らしい貢献をしましたが、本当に答えは全然問題ではありませんでした。私は研究を続けて、これが最も関連性の高い答えであると考えています。私はまだ他のソリューション(私は多くがあると確信しています)に心を開いていますので、より良い解決策があると思うなら、もっと答えてください! –

関連する問題