C# 用单一方法类——最好的方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/205689/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Class with single method -- best approach?
提问by JW.
Say I have a class that's meant to perform a single function. After performing the function, it can be destroyed. Is there any reason to prefer one of these approaches?
假设我有一个旨在执行单个功能的类。执行该功能后,它可以被销毁。有什么理由更喜欢这些方法之一吗?
// Initialize arguments in constructor
MyClass myObject = new MyClass(arg1, arg2, arg3);
myObject.myMethod();
// Pass arguments to method
MyClass myObject = new MyClass();
myObject.myMethod(arg1, arg2, arg3);
// Pass arguments to static method
MyClass.myMethod(arg1, arg2, arg3);
I was being intentionally vague about the details, to try to get guidelines for different situations. But I didn't really have in mind simple library functions like Math.random(). I'm thinking more of classes that perform some specific, complex task, but only require one (public) method to do it.
我故意在细节上含糊其辞,试图为不同情况制定指导方针。但我并没有真正想到像 Math.random() 这样的简单库函数。我正在考虑更多执行某些特定复杂任务的类,但只需要一个(公共)方法来完成它。
采纳答案by Mark S. Rasmussen
I used to love utility classes filled up with static methods. They made a great consolidation of helper methods that would otherwise lie around causing redundancy and maintenance hell. They're very easy to use, no instantiation, no disposal, just fire'n'forget. I guess this was my first unwitting attempt at creating a service oriented architecture - lots of stateless services that just did their job and nothing else. As a system grows however, dragons be coming.
我曾经喜欢充满静态方法的实用程序类。他们对辅助方法进行了很好的整合,否则会导致冗余和维护地狱。它们非常易于使用,无需实例化,无需处理,只需触发'n'forget。我想这是我第一次在不知情的情况下尝试创建面向服务的架构——许多无状态服务只是完成了他们的工作,没有别的。然而,随着系统的发展,龙即将到来。
Polymorphism
Say we have the method UtilityClass.SomeMethod that happily buzzes along. Suddenly we need to change the functionality slightly. Most of the functionality is the same, but we have to change a couple of parts nonetheless. Had it not been a static method, we could make a derivate class and change the method contents as needed. As it's a static method, we can't. Sure, if we just need to add functionality either before or after the old method, we can create a new class and call the old one inside of it - but that's just gross.
多态
假设我们有方法 UtilityClass.SomeMethod ,它愉快地嗡嗡作响。突然间,我们需要稍微改变一下功能。大多数功能是相同的,但我们必须更改几个部分。如果它不是静态方法,我们可以创建一个派生类并根据需要更改方法内容。由于它是静态方法,我们不能。当然,如果我们只需要在旧方法之前或之后添加功能,我们可以创建一个新类并在其中调用旧的类 - 但这太糟糕了。
Interface woes
Static methods cannot be defined through interfaces for logic reasons. And since we can't override static methods, static classes are useless when we need to pass them around by their interface. This renders us unable to use static classes as part of a strategy pattern. We might patch some issues up by passing delegates instead of interfaces.
接口问题
由于逻辑原因,不能通过接口定义静态方法。因为我们不能覆盖静态方法,所以当我们需要通过它们的接口传递静态类时,静态类是无用的。这使我们无法将静态类用作策略模式的一部分。我们可能会通过传递委托而不是接口来修补一些问题。
Testing
This basically goes hand in hand with the interface woes mentioned above. As our ability of interchanging implementations is very limited, we'll also have trouble replacing production code with test code. Again, we can wrap them up but it'll require us to change large parts of our code just to be able to accept wrappers instead of the actual objects.
测试
这基本上与上面提到的界面问题密切相关。由于我们交换实现的能力非常有限,我们也很难用测试代码替换生产代码。同样,我们可以将它们包装起来,但这需要我们更改大部分代码,以便能够接受包装器而不是实际对象。
Fosters blobs
As static methods are usually used as utility methods and utility methods usually will have different purposes, we'll quickly end up with a large class filled up with non-coherent functionality - ideally, each class should have a single purpose within the system. I'd much rather have a five times the classes as long as their purposes are well defined.
Fosters blob
由于静态方法通常用作实用方法,而实用方法通常具有不同的用途,我们很快就会得到一个充满不连贯功能的大类——理想情况下,每个类在系统中都应该有一个单一的用途. 只要它们的目的明确,我宁愿有五倍的课程。
Parameter creep
To begin with, that little cute and innocent static method might take a single parameter. As functionality grows, a couple of new parameters are added. Soon further parameters are added that are optional, so we create overloads of the method (or just add default values, in languages that support them). Before long, we have a method that takes 10 parameters. Only the first three are really required, parameters 4-7 are optional. But if parameter 6 is specified, 7-9 are required to be filled in as well... Had we created a class with the single purpose of doing what this static method did, we could solve this by taking in the required parameters in the constructor, and allowing the user to set optional values through properties, or methods to set multiple interdependent values at the same time. Also, if a method has grown to this amount of complexity, it most likely needs to be in its own class anyways.
参数蠕变
首先,这个可爱而天真的静态方法可能只需要一个参数。随着功能的增长,添加了几个新参数。很快就会添加更多可选参数,因此我们创建方法的重载(或仅添加默认值,使用支持它们的语言)。不久,我们就有了一个接受 10 个参数的方法。只有前三个是真正需要的,参数 4-7 是可选的。但是如果指定了参数6,7-9也需要填写...如果我们创建一个类的目的是做这个静态方法所做的事情,我们可以通过在构造函数,并允许用户通过属性设置可选值,或同时设置多个相互依赖的值的方法。此外,如果一个方法已经发展到这种复杂程度,
Demanding consumers to create an instance of classes for no reason
One of the most common arguments is, why demand that consumers of our class create an instance for invoking this single method, while having no use for the instance afterwards? Creating an instance of a class is a very very cheap operation in most languages, so speed is not an issue. Adding an extra line of code to the consumer is a low cost for laying the foundation of a much more maintainable solution in the future. And finally, if you want to avoid creating instances, simply create a singleton wrapper of your class that allows for easy reuse - although this does make the requirement that your class is stateless. If it's not stateless, you can still create static wrapper methods that handle everything, while still giving you all the benefits in the long run. Finally, you could also make a class that hides the instantiation as if it was a singleton: MyWrapper.Instance is a property that just returns new MyClass();
要求消费者无缘无故地创建类的实例
最常见的论点之一是,为什么要求我们类的使用者创建一个实例来调用这个单一方法,而之后却不再使用该实例?在大多数语言中,创建一个类的实例是一个非常便宜的操作,所以速度不是问题。向消费者添加额外的一行代码是一种低成本,可以为未来更易于维护的解决方案奠定基础。最后,如果您想避免创建实例,只需为您的类创建一个单例包装器,以便轻松重用——尽管这确实要求您的类是无状态的。如果它不是无状态的,您仍然可以创建处理所有内容的静态包装器方法,同时从长远来看仍然为您提供所有好处。最后,
Only a Sith deals in absolutes
Of course, there are exceptions to my dislike of static methods. True utility classes that do not pose any risk to bloat are excellent cases for static methods - System.Convert as an example. If your project is a one-off with no requirements for future maintenance, the overall architecture really isn't very important - static or non static, doesn't really matter - development speed does, however.
只有西斯处理绝对
的问题 当然,我不喜欢静态方法也有例外。不会造成任何膨胀风险的真正实用程序类是静态方法的极好案例 - 以 System.Convert 为例。如果你的项目是一次性的,不需要未来的维护,那么整体架构真的不是很重要——静态或非静态,并不重要——然而,开发速度很重要。
Standards, standards, standards!
Using instance methods does not inhibit you from also using static methods, and vice versa. As long as there's reasoning behind the differentiation and it's standardised. There's nothing worse than looking over a business layer sprawling with different implementation methods.
标准,标准,标准!
使用实例方法不会阻止您也使用静态方法,反之亦然。只要差异化背后有推理,并且是标准化的。没有什么比查看具有不同实现方法的业务层更糟糕的了。
回答by jjnguy
I prefer the static way. Since the Class is not representing an object it doesn't make sense to make an instance of it.
我更喜欢静态方式。由于 Class 不代表一个对象,因此创建它的实例是没有意义的。
Classes that only exist for their methods should be left static.
只为它们的方法存在的类应该保持静态。
回答by Robert
Can your class be made static?
你的类可以静态化吗?
If so, then I'd make it a 'Utilities' class that I would put all my one-function classes in.
如果是这样,那么我会把它变成一个“实用程序”类,我会把我所有的单一功能类都放进去。
回答by Ray Jezek
If there is no reason to have an instance of the class created in order to execute the function then use the static implementation. Why make the consumers of this class create an instance when one is not needed.
如果没有理由创建类的实例来执行函数,则使用静态实现。为什么要让这个类的消费者在不需要的时候创建一个实例。
回答by Chris Cudmore
I really don't know what the situation is here, but I would look at putting it as a method in one of the classes that arg1,arg2 or arg3 belong to -- If you can semantically say that one of those classes would own the method.
我真的不知道这里的情况是什么,但我会考虑将它作为一个方法放在 arg1、arg2 或 arg3 所属的类之一中——如果你能从语义上说这些类中的一个将拥有方法。
回答by Nathen Silver
I would say the Static Method format would be the better option. And I would make the class static as well, that way you wouldn't have to worry about accidentally creating an instance of the class.
我会说静态方法格式将是更好的选择。我也会使类成为静态的,这样您就不必担心意外创建类的实例。
回答by Bill the Lizard
If you don't need to save the stateof the object, then there's no need to instantiate it in the first place. I'd go with the single static method that you pass parameters to.
如果不需要保存对象的状态,那么一开始就不需要实例化它。我会使用您传递参数的单一静态方法。
I'd also warn against a giant Utils class that has dozens of unrelated static methods. This can get disorganized and unwieldy in a hurry. It's better to have many classes, each with few, related methods.
我还要警告一个巨大的 Utils 类,它有几十个不相关的静态方法。这可能会在匆忙中变得混乱和笨拙。最好有很多类,每个类都有很少的相关方法。
回答by Bill the Lizard
I would just do everything in the constructor. like so:
我只会在构造函数中做所有事情。像这样:
new MyClass(arg1, arg2, arg3);// the constructor does everything.
or
或者
MyClass my_object(arg1, arg2, arg3);
回答by Joel Wietelmann
If this method is stateless and you don't need to pass it around, then it makes the most sense to define it as static. If you DO need to pass the method around, you might consider using a delegaterather than one of your other proposed approaches.
如果这个方法是无状态的并且你不需要传递它,那么将它定义为静态是最有意义的。如果您确实需要传递该方法,您可以考虑使用委托而不是您提出的其他方法之一。
回答by Nick
I'd suggest that its hard to answer based on the information provided.
我建议根据提供的信息很难回答。
My gut is that if you are just going to have one method, and that you are going to throw the class away immediately, then make it a static class that takes all the parameters.
我的直觉是,如果您只打算拥有一个方法,并且您打算立即丢弃该类,那么将其设为一个接受所有参数的静态类。
Of course, its hard to tell exactly why you need to create a single class just for this one method. Is it the typical "Utilities class" situation as most are assuming? Or are you implementing some sort of rule class, of which there might be more in the future.
当然,很难确切地说明为什么需要为这种方法创建单个类。这是大多数人假设的典型的“公用事业类”情况吗?或者您是否正在实施某种规则类,将来可能会有更多规则类。
For instance, have that class be plugable. Then you'd want to create an Interface for your one method, and then you'd want to have all the parameters passed into the interface, rather than into the constructor, but you wouldn't want it to be static.
例如,让该类可以插入。然后您希望为您的一个方法创建一个接口,然后您希望将所有参数传递到接口中,而不是传递到构造函数中,但您不希望它是静态的。