1

この回答を見ると、私のプログラムで行ったように、C++ で友情を使用してプライベート ポインターをコピーしないでください。

class bar;

class foo
{
private:
   some_smart_pointer<int> state;

public:
   foo(int value) : state(new int(value)) {}
   friend class baz;
};

class bar
{
private:
   some_weak_pointer<int> state;
public:
   friend class baz;
};

class baz
{
public:
   foo Foo;
   bar Bar;

   baz() { Bar.state = Foo.state; }
};

それは問題ありませんが、一定のスマート ポインターを渡すと、カプセル化の原則に違反します。
システムの内部を公開します。bar を foo に渡すと、カップリングも作成されます。また、私のシステムでは、その質問で流暢なインターフェースと呼ばれるものにオブジェクトを集約することは理にかなっています。

MainObject.PropertyCollection.Property

そのSOの答えで言われているように、それはデメテルの法則に違反していませんか?
私はここで非常に混乱しています。
私は最後に自分のライブラリを再設計していますが、それを正しくしたいと思っています。
内部スマート ポインターを渡す代わりに、プロパティとしても使用されるラッパー クラスを渡し、それを読み取り専用に設定してから、コピーは安全だと思いましたか?

コメントに従って編集:まあ、私はD20 3.5 SRD(http://www.d20srd.org/)を実装しています。
たとえば、6 つの能力があります。
私の設計では、D20Abilities は D20Character 内に集約されています。
D20Abilities には、Strength、Dexterity、Constitution の 6 つの D20Ability インスタンスが含まれています。知恵、知性、カリスマ。
すべての D20Ability インスタンスは、システム全体で共有されるプライベート ステート (修飾子と呼ばれる) を保持します。たとえば、各スキルには独自の能力の修飾子が必要です。

4

1 に答える 1

2

あなたの説明とデメテルの法則に関して。ウィキペディアの例を使用すると、次のことを好むと言われています。

void exercise(const Dog& d) { return d.walk(); }

それ以外の:

void exercise(const Dog& d) { return d.legs.move(); }

犬は足を動かすのではなく、歩き方を知っている必要があるからです。これを D&D プログラムに適用すると、次のようになります。

bool hit_orc_with_long_sword(const Character& c, int DCValue) {
   return c.D20Abilities.Strength() + d20.roll() > DCValue;
}

優先: skill_check(c, MeleeAttack(LongSword(), Orc());

bool skill_check(const Character& c, const Action& a) {
    return c.attempt(a);
}

//.... in class character:

bool Character::attempt(const Action& a)
{
    return a.check_against(D20Abilities);
}

//.... in class Action:

bool Action::check_against(const D20Abilities& a) {
   return GetRelevantStat(a) + d20.roll() > DCValue;
}

このように、プロパティ グループを介してアクセスする代わりに、キャラクターはアクションを実行する方法を知っており、アクションは特定の統計で成功する可能性を知っています。インターフェイスを分離します。コンシューマー コード (上記の hit_orc_with_long_sword など) は、キャラクターの強さをチェックする方法を「伝える」必要はありません。それは、クラスの相互作用によって処理され、それぞれが明確に定義されたドメインを処理します。

ただし、提供されているコード サンプルには、いくつかの問題があるように見えます。friend を使用して特定の演算子を実装する以外のことを行っている場合、それは設計上の問題を示していることがわかります。あるオブジェクトから別のオブジェクトへと内部状態を変更するべきではありません。オブジェクトは、自身の内部状態と関数として渡された引数から一連のアクションを実行する方法を知っている必要があります。

于 2009-06-15T04:58:06.697 に答える