在我参加的几个最近的项目中,我几乎沉迷于以下编码模式: (我不确定是否有专有名称,但是无论如何...)

假设某个对象处于某种确定的状态,我们不会从外部改变这种状态。这些变化可能意味着任何行为,可以调用任何算法,但事实是,它们专注于改变状态 (成员国,数据状态等...) 某些对象。

让我们称呼一种更改这些对象的离散方式 Mutator. Mutators 被应用一次 (一般来说) 他们有一些内部方法 apply(Target& target, ...), ,这立即挑衅改变对象的状态 (实际上,它们是某种功能对象)。

它们也很容易被吸收到 并应用一对一(Mutator m1, m2, ...);他们还可以衍生出一些基本 BasicMutatorvirtual void apply(...) 方法。

我介绍了名为 InnerMutatorExplicitMutator 在访问方面有所不同 - 首先也可以改变 内部状态 对象的,应被称为朋友(friend InnerMutator::access;).


在这些项目中,我的逻辑转向以下方式工作:

  1. 准备可用的突变器,选择要应用的
  2. 创建并设置 object 到某个确定的状态
  3. foreach (mutator) mutator.apply(object);

现在的问题。

该方案转为运行良好,并且 (对我来说) 似乎是一些非标准但有用的设计模式的样本。

让我感到不舒服的是 InnerMutator 东西。 我认为将突变器宣布为每个对象可以更改的对象是一个好主意,我不会找到适当的选择。

这种情况可以通过 Mutators 还是您可以建议一些替代模式以相同的结果?

谢谢。

有帮助吗?

解决方案

我希望这不是进攻性的,但是我不禁认为这种设计是一个过于简单的问题,解决了一个相当简单的问题。

例如,为什么需要聚集突变器?一个人只能写:

template <class T>
void mutate(T& t)
{
    t.mutate1(...);
    t.mutate2(...);
    t.mutate3(...);
}

有您的聚合突变器,仅是一个简单的函数模板,依靠静态多态性,而不是组合的突变器列表制造一个超级突击器。

我曾经做过可能相当相似的事情。我制作了可以由操作员&&合并为应用两个操作数的超级函数对象(按从左到右的顺序)组合的函数对象,以便可以像以下方式一样编写代码:

foreach(v.begin(), v.end(), attack && burn && drain);

它真的很整洁,当时对我来说似乎真的很聪明,而且非常有效,因为它可以生成新的功能对象(不涉及运行时机制),但是当我的同事看到它时,他们以为我很疯狂。回想起来,我试图将所有内容都塞入功能风格的编程中,该编程具有有用性,但可能不应该在C ++中过度挂起。写作本来很容易:

BOOST_FOR_EACH(Something& something, v)
{
    attack(something);
    burn(something);
    drain(something);
}

当然,它是更多的代码行,但它具有集中式和易于调试的好处,并且不会向使用我的代码工作的其他人介绍外星概念。我发现重点放在紧密的逻辑上而不是试图强制减少代码线的情况下,我发现更有益。

我建议您对此深入思考,并真正考虑是否值得继续进行基于突变器的设计,无论它多么聪明和紧密。如果其他人无法快速理解它,除非您拥有促进作者的权威,否则很难说服人们喜欢它。

至于Innermutator,我认为您应该像瘟疫一样避免它。拥有可以在这里尽可能直接修改类内部的外部突变器类,这完全击败了拥有内部设备的许多目的。

其他提示

简单地做那些 Mutator他们正在改变的课程的方法?如果您希望有几个类具有共同的功能,那么为什么不使它们从同一基类继承?这样做将解决我想象的所有内部突变器不适。

如果要排队更改,则可以将它们作为函数调用集存储到类中的方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top