1

(これは C に似た環境です) car と bodyShop の 2 つのインスタンス オブジェクトがあるとします。車には、カラー iVar と対応するアクセサーがあります。bodyShop には、車のオブジェクトを取り込んでその色を変更する「paintCar」という名前のメソッドがあります。

実装に関しては、実際に bodyShop で車のオブジェクトの色を変更できるようにするには、2 つの方法があります。

  1. 「&」演算子を使用して、車へのポインターを渡します。次に、bodyShop は、色を変更する必要がある何らかのメソッドを実行するように車に指示するか、車のアクセサーを直接使用することができます。

  2. car オブジェクトを値で渡し、同じようなことを行って色を変更し、メソッドが新しい色の car オブジェクトを返すようにします。次に、元の車のオブジェクトを新しい車のオブジェクトに割り当てます。

オプション 1 の方が簡単に思えますが、OOP のベスト プラクティスに沿っているかどうか疑問に思っています。一般的に「最大OOP」の場合、「&」演算子は良いですか、それとも悪いですか? または、このスーパー OOPer を作成するためのより良いオプションを完全に見逃しているのかもしれません。お知らせ下さい :)

4

8 に答える 8

5

オプション 1 が推奨されます。

bodyShop は、色を変更する必要がある何らかのメソッドを実行するように車に指示するか、車のアクセサーを直接使用することができます。

さらに良いことに... IPaintable インターフェイスを作成します。Car に IPaintable を実装させます。BodyShop が Car ではなく IPaintable に依存するようにします。これの利点は次のとおりです。

  • BodyShop は IPaintable を実装するあらゆるもの (車、ボート、飛行機、スクーター) をペイントできるようになりました。
  • BodyShop は Car と密結合していません。
  • BodyShop はよりテストしやすいデザインになっています。
于 2009-10-08T20:54:53.887 に答える
3

bodyShop の責任は車のオブジェクトを変更することだと思いますので、#1 が正しい方法のように思えます。「&」演算子が必要な言語を使用したことがありません。通常、私の bodyShop オブジェクトは car.setColor(newColor) を呼び出します。この方法では、永続性の問題を含め、元の車の残りの属性について心配する必要はありません。そのままにしておくだけです。

于 2009-10-07T21:16:40.437 に答える
2

OOP のベスト プラクティスに関心があるため、オプション 2 で得られるパフォーマンス ヒットは無視する必要があります。注意すべき唯一のことは、いずれかのオプションを実行すると 2 つのクラス間の結合が不必要に増加すること、カプセル化に違反すること、ID が保持されることです。 .

これを考えると、オプション 2 はあまり望ましくありません。なぜなら、他のどのオブジェクトが元の車への参照を保持しているか、さらに悪いことに車を含んでいるかを判断できないからです。つまり、システム内の 2 つのオブジェクトが車の状態について異なる考えを持つ可能性があるため、同一性制約に違反します。システム全体の一貫性が失われるリスクがあります。

もちろん、特定の環境ではこれを避けることができますが、避けるのがベスト プラクティスであることは間違いありません。

最後に、bodyShop オブジェクトには状態がありますか。行動とアイデンティティ?必要最小限しか説明していないことは承知していますが、bodyShop は実際にはオブジェクトではない可能性があります。


ファンクショナル v OO アプローチ

興味深いことに、オプション 2 は関数型プログラミング環境でのアプローチに近いものです。状態の変更は許可されていないため、色が変更された場合に新しい車を作成することが唯一のアプローチになります。それはあなたが示唆しているものではありませんが、近いです。

これは完全にやり過ぎのように聞こえるかもしれませんが、コードと並列処理の正確性を証明する上で、いくつかの興味深い意味があります。

于 2009-10-07T21:25:36.000 に答える
1

この「Cライクな環境」が何を意味するのかわかりません。Cでは、これが必要です:

int paintCar(const bodyShop_t *bs, car_t *car);

車が指す内容を変更するところ。C の大きな構造体の場合、値ではなく常にポインターを関数に渡す必要があります。したがって、解決策 1 を使用します (「&」が C 演算子を意味する場合)。

于 2009-10-07T22:51:54.457 に答える
1

オプション1が私にとって勝ちます。& 演算子は、多くの OO 言語 (Java、Python など) で暗黙的です。その言語では「値渡し」を頻繁に使用しません。プリミティブ型のみがその方法で渡されます。

オプション 2 には複数の問題があります。車のコレクションがあり、それを認識していない機能によって、塗装のために車が bodyShop に送られ、見返りに新しい車を受け取り、車のコレクションが更新されない可能性があります見る?そして、よりイデオロギー的な観点から言えば、現実世界で変更するたびに新しいオブジェクトを作成する必要はありません。なぜ仮想オブジェクトでそうする必要があるのでしょうか? これは直感に反するだけなので、混乱を招きます。:-)

于 2009-10-07T21:42:51.220 に答える
0

それは、ボディ ショップの方法が失敗して、車が不確定な状態のままになる可能性があるかどうかにかかっています。その場合、車のコピー、または車の関連するすべての属性のコピーを操作することをお勧めします。次に、操作が成功した場合にのみ、それらの値を車にコピーします。そのため、ボディ ショップ方式で新しい車を古い車に割り当てることになります。これを正しく行うことは、C++ での例外の安全性のために必要であり、厄介なことになる可能性があります。

変更時に新しいオブジェクトを返すという他のパターンを使用することも可能であり、望ましい場合もあります。これは、元に戻す/やり直し、バックトラック検索を必要とする対話型システム、およびオブジェクトのシステムが時間の経過とともにどのように進化するかをモデル化することを含むあらゆるものに役立ちます。

于 2009-10-07T21:58:31.153 に答える
0

私も最初の 1 に同意します。これがベスト プラクティスとは言えません。なぜなら、他の人の心にどのようなベスト プラクティスがあるのか​​よくわからないからです。仕事のために働く。私はまた、hunspell win api や、私が使用しなければならなかった他の c-ish api で採用されたこのアプローチを見てきました。そうそう、私はスコットに同意します。

http://hunspell.sourceforge.net/

// 他の人のコードに興味がある場合に備えて

于 2009-10-07T21:22:14.827 に答える
0

他のオプションに加えて、オプション 1 により、paintCar メソッドは、車の色が正常に変更されたか、または問題があったかを示す完了コードを返すことができます。

于 2009-10-08T13:11:04.837 に答える