Java DRY 不泄露功能

问题描述 投票:0回答:1

假设我有几个类是“弱单例” - 不应该多次初始化的东西(注册侦听器等),但无论出于何种原因我不能使它们成为真正的单例甚至静态类,所以我能做的最好的事情就是警告自己(或者我想抛出一个

RuntimeException
,但就这个问题的目的而言,我如何处理它并不重要)。

public class WidgetManager {
    private static boolean initialized = false;

    // stuff to be initialized only once

    public WidgetManager() {
        if (initialized) Main.LOGGER.warn("Instantiating multiple instances of " + getClass().getName() + "!");

        // initialize stuff

        initialized = true;
    }
}

有几个这样的“弱单例”,所以手动输入它们会很累。另外,我感觉应该有更好的方法来进行检查,以免重复自己。

public class FooWidget {
    private static boolean initialized = false;

    // stuff

    public FooWidget() {
        if (initialized) // ...
        // ...
    }
}

public class BarWidget {
    // this gets tiring
}

接口中的私有函数不起作用 -

private
使得其中的函数仅在接口定义中可用。

public interface WeakSingleton {
    private void warnReinitialization(boolean initialized) {
        if (initialized) Main.LOGGER.warn("...");
    }
}

public class WidgetManager implements WeakSingleton {
    private static boolean initialized = false;

    public WidgetManager() {
        warnReinitialization(initialized); // <-- Error, function not visible

        initialized = true;
    }
}

default
有效,但它到处都暴露了它。

public interface WeakSingleton {
    default void warnReinitialization(boolean initialized) {
        // ...
    }
}

public class WidgetManager implements WeakSingleton {
    private static boolean initialized = false;

    public WidgetManager() {
        warnReinitialization(initialized); // <-- Works here

        initialized = true;
    }
}

public class Main {
    public static void main(String[] args) {
        new WidgetManager().warnReinitialization(); // <-- Oops, the interface "leaked" ...
    }
}

从表面上看,抽象类帮我定义了布尔值并检查它:

public abstract class WeakSingleton {
    protected static boolean initialized = false;

    protected void warnReinitialization() {
        if (initialized) System.out.println("Warning: Reinitializing " + getClass().getName() + "!");
    }
}

public class WidgetManager extends WeakSingleton {
    private FooWidget foo;
    private BarWidget bar;

    public WidgetManager() {
        warnReinitialization();
        
        System.out.println("WidgetManager ctor");

        initialized = true;
    }
}

public class FooWidget extends WeakSingleton {
    public FooWidget() {
        warnReinitialization();

        System.out.println("FooWidget ctor");

        initialized = true;
    }
}

public class BarWidget extends WeakSingleton {
    public BarWidget() {
        warnReinitialization();

        System.out.println("BarWidget ctor");

        foo = new FooWidget();
        bar = new BarWidget();

        initialized = true;
    }
}

public class Main {
    public static void main(String[] args) {
        new WidgetManager();
    }
}

不幸的是,它以其他方式损坏:

user@host:~ $ javac *
user@host:~ $ java Main
WidgetManager ctor
FooWidget ctor
Warning: Reinitializing BarWidget!
BarWidget ctor
user@host:~ $

抛开有问题的设计不谈,有没有一种方法可以实现我的目标,即减少检查所需的打字量而不泄漏检查功能?

感谢您的宝贵时间。

java dry
1个回答
0
投票

您可以创建构造函数

private
、类
final
并创建一个实例:

public final class WidgetManager {
    public static final WidgetManager INSTANCE = new WidgetManager();

    private WidgetManager() {
    }
}

但我认为您不需要为侦听器提供单例,只需每次创建一个新实例,即使实例没有任何不同。

© www.soinside.com 2019 - 2024. All rights reserved.