Java:[全局方法访问]单实例枚举vs按需对象构造vs静态
我想创建一个包含几个方法的类,这些方法可以在包中的任何位置使用。在阅读了enum自动提供了安全的实例化、序列化和防止在enum外部实例化后,我选择将enum与单个实例一起使用。我相信这是创造单身的最简单和安全的方式。但我的上司回来说这是肮脏的编程。真的吗?有人知道使用枚举代替对象构造和使用类传递引用的缺点吗?枚举何时初始化Java:[全局方法访问]单实例枚举vs按需对象构造vs静态,java,static,enums,object-reference,object-construction,Java,Static,Enums,Object Reference,Object Construction,我想创建一个包含几个方法的类,这些方法可以在包中的任何位置使用。在阅读了enum自动提供了安全的实例化、序列化和防止在enum外部实例化后,我选择将enum与单个实例一起使用。我相信这是创造单身的最简单和安全的方式。但我的上司回来说这是肮脏的编程。真的吗?有人知道使用枚举代替对象构造和使用类传递引用的缺点吗?枚举何时初始化 public enum Myenum { INSTANCE; public void init(...) {..initialize local varia
public enum Myenum {
INSTANCE;
public void init(...) {..initialize local variables...}
public method1 (...) {...}
public method2 (...) {...}
}
vs
vs
在我看来,使用第二种方法的缺点是,在我需要使用方法的任何地方都需要Myclass的对象引用,并且在对象构造时存在同步问题。在我的例子中,我并没有真正使用enum的序列化优势
enum是否隐式地提供了依赖项注入的好处?(即,可以在包内的任何地方访问Myenum的method1、method2,而无需担心实例创建)
我需要的enum的另一个特性是不能在enum外部重写enum内部的方法
我是否遗漏了一些明显的缺点?一个
enum
向其他程序员发出了一个语义信号,即它是一个具有一系列可能值的类型,您可以在switch语句中进行检查。然而,与人们通常在Java中使用的大多数其他模式相比,Enum可以被看作是一种更好的单例模式实现
如果您确定要使用单例模式,那么使用enum
可能没问题。然而,有些模式往往更灵活,更易于单元测试,更可靠,等等。如果有一天你决定不再希望它成为一个单独的模式,会怎么样?如果希望在数据库中进行某些更改时可以刷新,该怎么办?使用任何单例模式都会将您锁定在单例表示中,并使将来进行类似更改变得更加困难
工厂模式比单一模式更灵活,但在我看来,最好的模式是使用依赖注入。您可以单例绑定您的类型以避免重新实例化它的成本,但是类型本身(及其使用者)不需要绑定到特定的生存期或模式。我找到了一个答案,解释了为什么创建一个全局可访问的模式不好,而不是传递引用
摘录:
在实践中查看Java并发及其静态单例模式。看起来是这样的:
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}
它是安全的,因为静态是如何/何时初始化的,可能与枚举单例技巧是安全的原因相同
在JCIP的示例中,它返回一个东西,但是您可以添加所有您想要的静态方法,这些方法使用您想要在ResourceHolder中初始化的变量的数量。而且不需要init()调用。那个人解释了为什么他们认为它很脏吗?你能问他们吗?不,他有点“无论你的工作有多好,我都有足够的经验不同意你的意见”。他说的一件事是,这是一种干净方法的替代方法(创建一个对象并传递对它的引用)。我的想法是,如果enum隐式地提供了许多我上面提到的东西,为什么不直接使用它呢?即使在我的例子中我不需要它的一些好处(序列化)。这样使用它有什么缺点吗?除非您在依赖项注入中使用控制反转容器,否则您的
enum
解决方案可能是最好的。测试enum
解决方案并不容易,因为您无法控制进入构造函数的内容(如果有的话)。我的目标是防止不必要的引用传递和保护实例化。init只能被调用一次。我是如何多次实例化的?你不是。我指的是我自己。依赖注入是一个答案,但它需要增加一个框架和一些复杂的代码。Enum是一种简单的方法,它隐式地提供了这些东西,而不需要任何额外的框架。我的目标是保护实例化和不必要的引用传递。enum方法受到保护,不会被覆盖。@yalkris:依赖项注入是一种我发现效果很好的模式,它可以在没有框架的情况下使用,尽管框架可以提供帮助。但它确实倾向于一个全有或全无的命题:一旦你在一个地方开始使用这个模式,你就必须在任何地方使用它。工厂模式可以给您带来许多相同的好处,而不会如此普遍。但你比我更了解你的代码基础:如果你想要一个单身汉,我该和谁争论呢?;-)好发现。所以问题不一定是“enum-as-a-singleton”模式,而是通常的“singleton”模式。它服务于我使用singleton(可以在包中的任何地方访问的全局方法)的目标之一,但是使用singleton作为传递引用的替代方法有相同或更多的缺点。
public class Myclass {
public static void init(...) {...initialize local variables...}
public static method1 (...) {...}
public static method2 (...) {...}
}
public class ResourceFactory {
private static class ResourceHolder {
public static Resource resource = new Resource();
}
public static Resource getResource() {
return ResourceHolder.resource;
}
}