不确定用于这种特定情况的设计

时间:2016-06-16 04:35:54

标签: c++

例如,我有一个氏族和一个角色。有一个角色是领导者。为了给战队一个特定的特征,需要从角色中获得一些钱。

我不想太紧密耦合。现在我在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;
}

//也许是这个,看起来更糟糕的是:

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;
}

1 个答案:

答案 0 :(得分: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;
}

以上:

  • 影响clancharacter的逻辑分为clan_characters命名空间或struct / class(如果您需要)对于数据而言,而不是" clan_mngr"对我来说,这听起来像是一个或多个部落的资源管理对象

  • 如果get_clan()返回的类型更改为任何允许访问try_set_rank_by_id函数的指针语义

  • character类正在提供支持更高级别逻辑操作的try_pay()函数,所以稍后您可以执行类似make it atomic的操作并从多个线程调用它而不进行任何更改调用代码(例如,您不会有两个线程调用has_money(500),两者都只看到500,然后都花费它)

  • clan有一个try_set_rank_by_id函数,可以在内部管理逻辑检查是否允许字符id设置排名,以及更新哪个成员变量或数据结构。例如,如果引入了可以设置排名的副领导,则只需要更新try_set_rank_id的内部而不是客户端代码。

更多选项:

  • 您可以将clan作为函数参数传递:

    • template <typename Clan> bool give_rank_to_clan(Clan* my_clan, ...),授予最大的&#34;鸭子打字&#34;在测试期间自由提供任意模拟部族类型,或

    • 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,则不必更改该功能但是,这会使clancharacter更紧密地联系起来:短期内至少需要知道调用id() - 没有完美的选择。