2016-06-16 5 views
0

たとえば、私は一族と文字を持っています。リーダーである人物がいる。一族に特定の機能を与えるためには、キャラクターからいくらかのお金が必要です。この特定のケースでどのようなデザインを使用するのかは不明です

私は強くカップリングしたくないです。今、私はこのようclanクラスのメンバを持っている:

bool clan::give_rank(character* chr, int rank) 
{ 
    if (!is_leader(chr.id()) || !chr->has_money(500)) 
     return false; 

    this->rank_ = rank; 
    chr->take_money(500); 
    return true; 
} 

は、この密結合ですか?または、私は両方のクラスを接続するclan_mgrのようなセカンダリクラスを持っているはずですか?

bool clan_mngr::give_rank(character* chr, int rank) 
{ 
    clan* myclan = chr->get_clan(); 

    if (!myclan || !myclan->is_leader(chr.id()) || !chr->has_money(500)) 
     return false; 

    myclan->rank_ = rank; 
    chr->take_money(500); 
    return true; 
} 

//それともさらに悪いIMOに見えるこの1、:

bool character::give_rank_to_clan(int rank) 
{ 
    clan* myclan = chr->get_clan(); 

    if (!myclan || !myclan->is_leader(id()) || !has_money(500)) 
     return false; 

    myclan->rank_ = rank; 
    TakeMoney(500);  
    return true; 
} 

答えて

0

デカップリングは芸術のビットですが、あなたはクラス間のAPIの使用量を削減し、正式しようとしています。考えてみましょう:

bool clan_characters::give_rank_to_clan(character& c, int rank) 
{ 
    auto clan = c.get_clan(); 
    if (clan) 
     if (c.try_pay(500)) 
      if (clan->try_set_rank_by_id(rank, c.id()) 
       return true; 
      else 
       c.try_pay(-500); // always works for -ve amount ;-) 
    return false; 
} 

を上記の場合:

  • clan sおよびcharacterの両方に影響を与えるロジックはなく、clan_characters名前空間またはstruct/class(あなたがデータの必要性を発見した場合)に分離され、 "clan_mngr"私には1つ以上の氏族のリソース管理オブジェクトのように聞こえます

  • あなたは何かを修正する必要はありませんそれは原子・コール作るような何かを行うことができますあなたにそう後で、try_set_rank_by_id機能

  • characterクラスは、より高いレベルの論理演算をサポートtry_pay()機能を提供しているへのアクセスを可能にするポインタのセマンティクスを使って何にget_clan()変化によって返されたPE呼び出しコードを変更することなく複数のスレッドからあなたは、両方の両方が

  • clanが論理文字のIDがランクを設定することが許可されているかどうかを確認、管理、内部でできtry_set_rank_by_id機能を持っている)、それを費やし、そして、唯一の500を参照してください、2つのスレッドがhas_money(500)を呼び出す必要はありませんどのメンバー変数またはデータ構造が更新されるか。たとえば、ランクを設定できる副指導者が導入された場合は、クライアントコードではなく、try_set_rank_idの内部のみを更新する必要があります。

    • template <typename Clan> bool give_rank_to_clan(Clan* my_clan, ...)、任意の供給するために最大の "ダックタイピング" の自由を付与します。あなたはclanは、関数の引数、いずれかのようである渡すことができ

      その他のオプションを試験中にモッククランの種類、または

    • bool give_rank_to_clan(decltype(character::get_clan()) my_clan, ...)またはちょうどclan* my_clanですが、引き続きclanの派生型を渡すことができます。 clan::try_set_rank_by_id()virtual

  • 行われた場合、テストのために最も有用なあなたはtry_set_rank_by_character(rank, c)を持つことができます - try_set_rank_by_characterではなくidの文字データの他のいくつかの側面を使用したい場合は、この関数を意味する変更する必要はありませんが、それはカップルclanをより厳密にcharacterにしています:短期間では少なくとも電話するために知る必要がありますid() - 完璧な選択はありません。

関連する問題