C++程序设计问题
在我最近参与的几个项目中,我几乎沉迷于以下编码模式:(我不确定是否有合适的名称,但无论如何......)
让我们说某个对象处于某种确定的状态,我们不想从外部改变这种状态。这些更改可能意味着任何行为,可以调用任何算法,但事实是它们专注于更改某些对象的状态(成员状态、数据状态等)。
我们将改变这些对象的一种离散方法称为“Mutator”。 Mutators
应用一次(通常),并且它们有一些内部方法,例如 apply(Target& target, ...)
,它会立即引发更改对象的状态(事实上,它们是某种功能对象)。
它们也可以很容易地被同化为链并一一应用(<代码>变异器 m1, m2, ...);它们还可以通过 virtual void apply(...)
方法从一些基本的 BasicMutator
派生。
我引入了名为 InnerMutator
和 ExplicitMutator
的类,它们在访问方面有所不同 - 第一个类还可以更改对象的内部状态,并且应该被声明为好友(friend InnerMutator::access;
)。
在这些项目中,我的逻辑按照以下方式工作:
- 准备可用的变异器,选择要应用的
- 创建并将
对象
设置为某个确定的状态 foreach(变异器) mutator.apply(object);
现在是问题。
这个方案效果很好并且 (对我来说)似乎是一些非标准但有用的设计的样本 图案。
让我感到不舒服的是
InnerMutator
的东西。我不这么认为 考虑将 mutator 声明为朋友 每个对象的状态可能是 改变是个好主意,但我不想 找到合适的替代方案。这种情况可以通过
Mutators
来解决吗?或者您可以 建议一些替代模式 相同的结果?
谢谢。
In couple of recent projects that I took part in I was almost addicted to the following coding pattern: (I'm not sure if there is a proper name for this, but anyway...)
Let's say some object is in some determined state and we wan't to change this state from outside. These changes could mean any behaviour, could invoke any algorithms, but the fact is that they focus on changing the state (member state, data state, etc...) of some object.
And let's call one discrete way of changing those object a Mutator
. Mutators
are applied once (generally) and they have some internal method like apply(Target& target, ...)
, which instantly provokes changing the state of the object (in fact, they're some sort of functional objects).
They also could be easily assimilated into chains and applied one-by-one (Mutator m1, m2, ...
); they also could derive from some basic BasicMutator
with virtual void apply(...)
method.
I have introduced classes called InnerMutator
and ExplicitMutator
which differ in terms of access - first of them can also change the internal state of the object and should be declared as a friend (friend InnerMutator::access;
).
In those projects my logic turned to work the following way:
- Prepare available mutators, choose which to apply
- Create and set the
object
to some determined state foreach (mutator) mutator.apply(object);
Now the question.
This scheme turnes to work well and
(to me) seems as a sample of some non-standard but useful design
pattern.What makes me feel uncomfortable is that
InnerMutator
stuff. I don't
think declaring mutator a friend to
every object which state could be
changed is a good idea and I wan't to
find the appropriate alternative.Could this situation be solved in terms of
Mutators
or could you
advice some alternative pattern with
the same result?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我希望这不会被冒犯,但我忍不住认为这种设计对于一个相当简单的问题来说是一个过于花哨的解决方案。
例如,为什么需要聚合变异器?人们可以简单地写:
这是你的聚合变异器,只是它是一个依赖静态多态性的简单函数模板,而不是构成一个超级变异器的变异器组合列表。
我曾经做过一些可能非常相似的事情。我制作了可以通过运算符 && 组合的函数对象到应用两个操作数的超级函数对象中(按从左到右的顺序),这样就可以编写如下代码:
它真的很整洁,当时对我来说似乎很聪明,而且它非常高效,因为它在苍蝇(不涉及运行时机制),但是当我的同事看到它时,他们认为我疯了。回想起来,我试图将所有内容都塞进函数式编程中,函数式编程有其用处,但在 C++ 中可能不应该过度依赖。编写起来很容易:
虽然代码行数较多,但它的优点是集中且易于调试,并且不会向使用我的代码的其他人引入外来概念。我发现专注于严格的逻辑比尝试强制减少代码行更有益。
我建议您深入思考这一点,并真正考虑是否值得继续这种基于突变的设计,无论它多么聪明和紧凑。如果其他人不能很快理解它,除非你有Boost作者的权威,否则很难说服人们喜欢它。
至于InnerMutator,我认为你应该像躲避瘟疫一样避开它。拥有可以像这里一样直接修改类内部的外部变异器类,完全违背了拥有内部的很多目的。
I hope this isn't taken offensively, but I can't help but think this design is an overly fancy solution for a rather simple problem.
Why do you need to aggregate mutators, for instance? One can merely write:
There's your aggregate mutator, only it's a simple function template relying on static polymorphism rather than a combined list of mutators making one super-mutator.
I once did something that might have been rather similar. I made function objects which could be combined by operator && into super function objects that applied both operands (in the order from left to right) so that one could write code like:
It was really neat and seemed really clever to me at the time and it was pretty efficient because it generated new function objects on the fly (no runtime mechanisms involved), but when my co-workers saw it, they thought I was insane. In retrospect I was trying to cram everything into functional style programming which has its usefulness but probably shouldn't be over-relied on in C++. It would have been easy enough to write:
Granted it is more lines of code but it has the benefit of being centralized and easy to debug and doesn't introduce alien concepts to other people working with my code. I've found it much more beneficial instead to focus on tight logic rather than trying to forcefully reduce lines of code.
I recommend you think deeply about this and really consider if it's worth it to continue with this mutator-based design no matter how clever and tight it is. If other people can't quickly understand it, unless you have the authority of boost authors, it's going to be hard to convince people to like it.
As for InnerMutator, I think you should avoid it like the plague. Having external mutator classes which can modify a class's internals as directly as they can here defeats a lot of the purpose of having internals at all.
简单地为它们正在更改的类创建这些
Mutator
方法不是更好吗?如果您希望多个类具有共同的功能,那么为什么不让它们继承同一个基类呢?这样做可以解决我想象中的所有内在变异的不适。如果您想要对更改进行排队,您可以将它们存储为对类中方法的函数调用集。
Would it not be better to simply make those
Mutator
s methods of the classes they're changing? If there's common functionality you want several classes to have then why not make them inherit from the same base class? Doing this will deal with all the inner mutator discomfort I would imagine.If you want to queue up changes you could store them as sets of function calls to the methods within the classes.