过度概括函数的名称?这是一种反模式吗?
将参数传递给函数以选择该函数执行的操作的名称是什么?
例如:
enum {
DoSomething,
...
};
void f(FunctionType a);
f(DoSomething);
....
f(DoSomethingElse);
对比:
void DoSomething();
....
void DoSomethingElse();
What is the name for passing an argument to a function to select what the function does?
For example:
enum {
DoSomething,
...
};
void f(FunctionType a);
f(DoSomething);
....
f(DoSomethingElse);
Vs:
void DoSomething();
....
void DoSomethingElse();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
一般来说,人们可以将其视为一种反模式,因为单独的方法更简单、更明确。然而,某些情况可能会改变这种观点。两个例子:
前端控制器
所有前端控制器模式都像这样工作(Struts 或更高版本):调用带有参数的集中方法;它随后被分派到正确的处理程序(由参数之一标识)。这里的要点是在许多特定代码之前(和之后,可能有例外)应用通用代码。
问题不在于执行此类代码,而在于将其包含在您自己的代码中。如果它在框架代码中(已经编写、经过良好测试等),那就没问题。
示例包括所有拦截技术,例如 Spring。
Command
Command
模式可能非常接近:In general, one could see it as an anti-pattern, as the separate methods are simpler and more explicit. However, some contexts may change this opinion. Two examples:
Front Controller
All
Front Controller
patterns work like this (Struts or later) : the call is made to a centralized method, with parameters ; it is later dispatched to the correct handler (identified by one of the parameters). The point here is to apply a common code before (and after, possibly for exceptions) many specific codes.The problem is not that this type of code executes, but to have this in your own code. If it is in framework code (already written, well tested etc), it's fine.
Examples are all the interception technologies, like Spring ..
Command
The
Command
pattern may be pretty close :像这样的结构通常与迭代所有值的循环一起出现。在这种情况下,它是一种伪装的循环切换模式。
但这本身并不是一种反模式。如果您事先不知道参数,这样的设计可能是有效的。
Constructs like these often appear together with loops iterating over all values. In that case it's a disguised loop-switch pattern.
But that's not an anti-pattern per se. If you do not know the parameters in advance, a design like this can be valid.
我将您在“动作”或“动词”中传递的参数称为“动作”。我还没有看到这个命名为模式。您没有显示的是不可避免的
switch
语句,我认为这就是您将其称为反模式的原因。您可以认为这是命令模式的糟糕实现。维基百科有一篇关于函数对象的文章,它也是一个糟糕的实现。
在面向对象语言流行之前,我们通过类似的方式将函数分组到对象中,通常将其称为“调度”。 (这个名字已经被包含在模式世界中,有不同的东西。)
I've called the parameter you pass in the "action" or the "verb". I haven't seen this named as pattern. What you don't show is the inevitable
switch
statement, which is-- I assume-- why you are calling it an antipattern.You could consider it a bad implementation of the command pattern. And wikipedia has a article on function objects, which it is also a bad implementation of.
Before object oriented languages were prevalent, we did things like this to group functions in to objects, and often called it "dispatching". (This name has been subsumed in the pattern world with a different thing.)
控制耦合。
我在 Jim Weirich 的演讲中听说过这一点。一般来说,该方法将有一个“标志”参数来控制使用什么算法。
请参阅我的笔记(以及一些参考资料),网址为软件设计的大统一理论。
Control Coupling.
I heard about it in a presentation by Jim Weirich. In general the method will have a "flag" parameter that controls what algorithm to use.
See my notes (with some references) at Grand Unified Theory of Software Design.
它不一定是反模式!
即使 f() 函数是一个大开关,它也可以是一个方便的地方,可以处理特定“语言”的各个“标记/动词/指令/原子”(或者更确切地说“发送进行处理”)。此外,f() 函数还可以引入逻辑来决定如何根据运行时上下文分派特定动词。这种以简单、集中的方式将文本/数据动词后期绑定到特定方法的能力很重要,即使在其他情况下,使用面向对象语言的多态和内省功能来实现该目的可能更合适。
编辑:请参阅 KLE 的回应,因为它呼应了这是一种模式的想法。 KLE 还提供了相同/相似的命令和前端控制器模式的参考。
It not necessarily an anti-pattern!
Even when the f() function is one big switch, it can be a convenient place where individual 'tokens/verbs/instructions/atoms' of a particular 'language' are processed (or rather 'sent for processing'). Furthermore the f() function can also introduce logic to decide how to dispatch a particular verb based on the run-time context. This ability to late-bind text/data verbs to particular methods in a simple, centralized fashion is important, even though in other cases, using the polymorphic and introspective features of OO languages to serve that purpose may be more appropriate.
Edit: see KLE's response as it echos the idea that this is a pattern. KLE also provides reference to Command and the Front Controller patterns which are same/similar.
这将成为重构的目标,通过为每种情况创建单独的方法名称并将任何公共代码放入通常调用的方法中。
This would be a target for refactoring by creating separate method names for each case and placing any common code into a commonly-called method.
我将其称为调度程序,因为它可能会根据参数调用更具体的代码。
过于通用的功能可能会很糟糕:难以使用、难以维护、难以调试。它们过于笼统的性质使得很难断言前置条件、后置条件和不变量。尽管如此,调度程序确实有其偶尔的用途。这是提供可扩展性的一种方法——有时这是比传统模式更实用的方法。
I'd call it a Dispatcher, since it's probably going to call more specific code based on the parameter(s).
Overly general functions can be bad: hard to use, hard to maintain, hard to debug. Their overly-general nature makes it hard to assert pre- and post-conditions and invariants. Nevertheless, Dispatchers do have their occasional uses. It is one way to provide for extensibility--sometimes it's a more practical way that traditional patterns.
这个例子可以被认为是一个过早泛化
代码
对比
This example could be considered a Premature Generalization
The code
Vs