简体   繁体   English

使用java中的方法的单个实例

[英]Single instance with methods in java

I am wondering about programming decision - which I think is matter of style. 我想知道编程决策 - 我认为这是风格问题。 I need to have single instance of class which has only methods and no attributes. 我需要有一个只有方法而没有属性的类的单个实例。 To obtain that in java I have two options: 要在java中获得它,我有两个选择:

  1. create an abstract class with static methods within, thus it will not be possible to create any instance of the class and that is fine, 使用静态方法创建一个抽象类,因此不可能创建该类的任何实例,这很好,
  2. use a singleton pattern with public methods. 使用公共方法的单例模式。

I tend to go for second approach although met with 1. Which and why is better of those, or there is third option. 我倾向于采用第二种方法,尽管遇到1.哪种以及为什么这些更好,或者有第三种选择。

Would it make sense for that singleton to implement an interface, allowing you to mock out those methods for test purposes? 这个单例实现一个接口是否有意义,允许你模拟这些方法用于测试目的?

I know it goes against testing dogma these days, but in certain situations I think a static method is fine. 我知道这些日子反对测试教条,但在某些情况下我认为静态方法很好。 If it's the kind of behaviour which you're never going to want to fake for test purposes, and which is never going to be polymorphic with other implementations, I don't see much point in making a singleton. 如果这是一种你永远不想为了测试目的而假装的行为,并且它永远不会与其他实现一起变成多态,我认为制作一个单例并不重要。 (Singletons are also generally the enemy of testability, although if you only directly refer to them in the injection part of your code, they can implement appropriate interfaces so their singletoneity never becomes a problem.) (单身人士通常也是可测试性的敌人,尽管如果你只在代码的注入部分直接引用它们,他们就可以实现适当的接口,这样他们的单一性就不会成为问题。)

It's worth mentioning that C# has "static classes" for this kind of situation - not only do they prohibit other code from deriving from or instantiating the class, but you can't even use it as a parameter. 值得一提的是,C#在这种情况下具有“静态类” - 它们不仅禁止其他代码派生或实例化类,而且甚至不能将它用作参数。 Basically it signals the intent very clearly. 基本上它非常清楚地表明意图。

I would definitely suggest at least having a private constructor to prevent instantiation by the outside world. 我肯定建议至少有一个私有构造函数来防止外部世界的实例化。

My personal view is that the class should contain a private constructor and NOT be abstract. 我个人认为,该类应该包含一个私有构造函数,而不是抽象的。 Abstract suggest to a reader that there is a concrete version of the class somewhere, and they may waste time searching for it. 摘要向读者建议某个地方有一个具体的版本,他们可能会浪费时间去寻找它。 I would also make sure you comment your code effectively. 我还要确保你有效地评论你的代码。

public class myClass {

   /** This class should never be instantiated. */
   private myClass() {
   }

   public static void myMethod() {

   }

   ...
   //etc
   ...
}

For option #1, it may not even be that important to restrict instantiation of your static utility class. 对于选项#1,限制静态实用程序类的实例化可能甚至不重要。 Since all it has is static methods and no state, there is no point - but neither harm - instantiating it. 因为它只有静态方法而且没有状态,所以没有任何意义 - 但是没有任何伤害 - 实例化它。 Similarly, static methods can't be overridden so it does not make sense - nor difference - if it is subclassed. 类似地,静态方法不能被覆盖,因此如果它是子类,则没有意义 - 也没有区别。

If it had any state, though - or if there is a chance that it will get stateful one day - it may be better to implement it as a normal class. 如果它有任何状态 - 或者如果它有可能在某一天获得有状态 - 那么将它作为普通类实现可能会更好。 Still I would prefer not to use it as a Singleton, rather to pass its sole instance around via dependency injection. 我仍然不希望将它用作Singleton,而是通过依赖注入传递其唯一的实例。 This makes unit testing so much easier in the long run. 从长远来看,这使得单元测试变得更加容易。

If it holds a state I would use the singleton pattern with private constructors so you can only instantiate from within the class. 如果它保持状态,我将使用带有私有构造函数的单例模式,因此您只能从类中实例化。 If it does not hold a state, like the apache commons utility classes, I would use the static methods. 如果它没有状态,比如apache commons实用程序类,我会使用静态方法。

I've never seen the problem with static methods. 我从未见过静态方法的问题。 You can think of static methods as somehow breaking OO, but they make perfect sense if you think of static as a marker that something is stateless. 您可以将静态方法视为以某种方式破坏OO,但如果您将静态视为某种无状态的标记,它们就会非常有意义。 You find this in the java apis in places like java.Math. 你可以在Java apis中找到这个,比如java.Math。 If you're worried about subclassing you can always make it final. 如果您担心子类化,您可以始终将其作为最终。

There is a danger in that a class like that can end up as a "utility method garbage can", but as long as the functionality doesn't diverge too much then there's nothing wrong with it. 存在这样的危险:像这样的类可能最终成为“实用方法垃圾箱”,但只要功能不会分散太多,那么它就没有任何问题。

It's also clearer, as there's no need to manage an object lifecycle like you would with a singleton (and since there's no state, what's the point of that anyway?). 它也更清晰,因为没有必要像使用单例一样管理对象生命周期(并且由于没有状态,无论如何都有什么意义?)。

For a single instance, I suggest you have an enum, with one instance. 对于单个实例,我建议你有一个枚举,有一个实例。

However, for a class with no attributes, you don't have to have an instance. 但是,对于没有属性的类,您不必拥有实例。 You can use a utility class. 您可以使用实用程序类。 You can use an enum, with no instances and only static methods. 您可以使用枚举,没有实例,只有静态方法。 Note: this cannot be easily mocked out. 注意:这不容易被嘲笑。

You can still implement an interface if you ever need to mock out the implementation in testing. 如果您需要在测试中模拟实现,您仍然可以实现接口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM