Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在使用枚举版本的单例模式时,修改单例类代码是扩展单例功能的唯一方法吗?_Java_Design Patterns_Enums_Singleton - Fatal编程技术网

Java 在使用枚举版本的单例模式时,修改单例类代码是扩展单例功能的唯一方法吗?

Java 在使用枚举版本的单例模式时,修改单例类代码是扩展单例功能的唯一方法吗?,java,design-patterns,enums,singleton,Java,Design Patterns,Enums,Singleton,最近,当我询问时,有人告诉我使用enum版本的单例模式是一个不错的选择。并通过多个线程。如果该方法有副作用(更改某些变量的状态),则需要考虑保护它(使其同步)或其部分。所以我写的代码如下: public enum ReStation { INSTANCE; private List<Email> emailList; private ReStation() { emailList = new ArrayList<>();

最近,当我询问时,有人告诉我使用enum版本的单例模式是一个不错的选择。并通过多个线程。如果该方法有副作用(更改某些变量的状态),则需要考虑保护它(使其同步)或其部分。所以我写的代码如下:

public enum ReStation {
    INSTANCE;  

    private List<Email> emailList;

    private ReStation() {
        emailList = new ArrayList<>();
    }

    public synchronized void recycleEmail(Email email) {
        System.out.println("Recycle station recycleing the email: "
                        + email.getContent());
        emailList.add(email);
    }

    public synchronized void deleteEmail(Email email) {
        emailList.remove(email);
    }

    public synchronized void clear() {
        emailList.clear();
    }
}
公共枚举重新启动{
实例;
私人名单;
私人造林(){
emailList=新的ArrayList();
}
公共同步作废回收邮件(电子邮件){
System.out.println(“回收站回收电子邮件:”
+email.getContent());
emailList.add(电子邮件);
}
公共同步无效删除电子邮件(电子邮件){
电子邮件列表。删除(电子邮件);
}
公共同步无效清除(){
emailList.clear();
}
}
然而,当我读到《可重用面向对象软件的设计模式元素》一书时,我遇到了如下一段:

适用性

•一个类必须只有一个实例,并且必须可供用户访问 来自知名接入点的客户端。
•当唯一实例应通过子类化进行扩展时,以及 应该能够在不修改代码的情况下使用扩展实例

鉴于枚举无法扩展,我真的很困惑,在使用枚举版本的单例模式时,如何在不修改扩展实例代码的情况下使用扩展实例?修改singleton类代码是扩展singleton功能的唯一方法吗?

当引用说“应通过子类化扩展唯一实例”时,他们谈论的是以下情况:

  • 您需要一个基类或接口的单个可分辨实例,以及一个众所周知的访问点,如进程
    记录器

  • 您需要在运行时选择具体的实现,例如基于配置或其他运行时信息。例如,可以通过
    FileLogger
    ConsoleLogger
    实现进程
    Logger
    。通常,应该可以使用任何
    Logger
    子类来实现系统记录器

“enum版本单例模式”无法做到这一点。

当引文中提到“应通过子类化扩展唯一实例”时,他们讨论的是以下情况:

  • 您需要一个基类或接口的单个可分辨实例,以及一个众所周知的访问点,如进程
    记录器

  • 您需要在运行时选择具体的实现,例如基于配置或其他运行时信息。例如,可以通过
    FileLogger
    ConsoleLogger
    实现进程
    Logger
    。通常,应该可以使用任何
    Logger
    子类来实现系统记录器


“enum版本的单例模式”无法做到这一点。

如果可以扩展它,它就不是真正的单例模式。我认为单例模式的全部目的是可以扩展,否则我们只能使用静态类?我不是专业的编码人员,但我想他们的意思是扩展它,重写一个方法,调用super.method()要重用旧的工厂方法(meat and Potations),然后当应用程序经历生命周期并需要更新时,您可以执行依赖注入或其他操作?@shmosel修改单例类代码是扩展单例功能的唯一方法吗?这是一个奇特的引用。没有更多的上下文,我很难理解它。我的猜测是,它前面有一些类似“您不想使用枚举…”的内容,这意味着,您可能最初将重新启动编码为非枚举类,因此您可以编写
publicstaticfinalinstance=newrestation()
同时具有稍后将其更改为
公共静态最终实例=新SpecializedReStation()的选项不破坏任何使用实例的代码。如果你可以扩展它,它就不是一个真正的单例。我认为单例的全部目的是它可以扩展,否则我们只会使用一个静态类?我不是专业的程序员,但我想他们的意思是你扩展它,重写一个方法,调用super.method()以重用旧的工厂方法(肉和土豆),然后你可以做依赖注入之类的事情,或者当应用程序经历其生命周期并需要更新时,你还做了什么?@shmosel正在修改单例类代码,这是扩展单例功能的唯一方法?这是一个奇怪的引语。没有更多的上下文,我很难理解它。我猜它前面有类似“您不想使用枚举…”的内容,这意味着,您可能最初将重新启动编码为非枚举类,因此可以编写
publicstaticfinalinstance=newrestation()
同时可以选择稍后将其更改为
公共静态最终实例=新的SpecializedReStation();
而不中断使用实例的任何代码。