例如,我有一个氏族和一个角色。有一个角色是领导者。为了给战队一个特定的特征,需要从角色中获得一些钱。
我不想太紧密耦合。现在我在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;
}
答案 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;
}
以上:
影响clan
和character
的逻辑分为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
,则不必更改该功能但是,这会使clan
与character
更紧密地联系起来:短期内至少需要知道调用id()
- 没有完美的选择。