Java中“库”的设计模式?

时间:2012-08-29 08:34:03

标签: java design-patterns

我正在寻找一套方法的设计模式,这些方法将在几个项目中使用,所以我正在用它们创建一个“库”。

起初我想让所有这些都是静态的,所以它们可以被Library.methodName()调用,就是这样。我做了并意识到我为每个方法传递了几个常量值,这些方法可以设置一次然后在类中使用。 (这个常数值在项目之间变化)

现在我想到了一个必须用这个值实例化的类,并且每次都不通过值来访问对象的方法,但是我想每次都阻止创建“Library”类的对象我想到了辛格尔顿。

我确实使用所有这些制作了一个Singleton,但是我需要首先为类变量创建一个显式的set,但这种方法要求程序员现在必须在使用之前设置该值。方法,即使是我自己,最终也会使它失败。

一直在做Singleton.getInsance(value1, value2).method(...)是不可能的,我更喜欢我最初的方法。此外,我无法为此变量定义“默认”值,它们必须设置。

是否有一个设计模式可以帮助我拥有一个可以使用给定值初始化而不必一直传递它们的Singleton?

或者我应该坚持使用我的初始方法并让程序员一直传递值?

或任何其他选项,任何适合的设计模式或其他任何可能也适用。

由于

6 个答案:

答案 0 :(得分:0)

  

我应该坚持使用我的初始方法并让程序员一直传递值吗?

我能看到的唯一替代方法是为上下文创建一个构造函数,该上下文包含并设置所有必需值。如果可以的话,我会避免使用有状态的单身人士。

如果调用者想要避免多次创建对象,他们可以根据需要将其设为单例,但是你不应强迫他们使用单例。

答案 1 :(得分:0)

或者,由于这些值在项目之间而不是在项目内部发生变化,因此您的“库”可以读取配置文件,为您提供值value1, value2,以便调用代码不需要每次都给它们。 / p>

这将是一个懒惰的读取(在第一次调用时进行),因此您还可以确保在使用之前初始化库。如果文件当然不存在,您可能希望抛出未经检查的异常。

答案 2 :(得分:0)

这对你来说这样舒服吗?

public class AreaCalculator {
  private int length = 10;
  private int width = 10;
  private static final AreaCalculator areaCalculator = new AreaCalculator();

  private AreaCalculator() {
    // TODO Auto-generated constructor stub
  }

  public static AreaCalculator getInstance() {
    return areaCalculator;
  }

  public AreaCalculator fillLength(int length) {
    this.length = length;
    return getInstance();
  }

  public AreaCalculator fillWidth(int width) {
    this.width = width;
    return getInstance();
  }

  public AreaCalculator fillAll(int length, int width) {
    this.length = length;
    this.width = width;
    return getInstance();
  }

public int calculateArea() {
    if (!isInit()) {
        throw new RuntimeException("Should Init first!");
    }
    return length * width;
}

public boolean isInit() {
    // add something
    return true;
}

测试代码

public class TestMain {

  public static void main(String[] args) {
    int result = AreaCalculator.getInstance().fillWidth(20).calculateArea();
    System.out.println("10*20=" + result);
    result = AreaCalculator.getInstance().fillWidth(10).fillLength(10).calculateArea();
    System.out.println("10*10=" + result);
    result = AreaCalculator.getInstance().fillAll(10, 30).calculateArea();
    System.out.println("10*30=" + result);
  }

**

  

使用Config界面。

**

ConfigInf(lib side)

public interface ConfigInf {

    public static String F_LENGTH = "length";
    public static String F_WIDTH = "width";

    public String getProperty(String key);

}

ConfigFactory(lib side)

public class ConfigFactory {

    private static ConfigInf config = null;

    public static void init(ConfigInf config) {
        ConfigFactory.config = config;
    }

    public static ConfigInf getConfig() {
        if (config == null) {
            throw new NullPointerException("Config should be init first");
        }
        return config;
    }
}

ClientConfig(客户端)

public class ClientConfig implements ConfigInf {

    String value = "10";

    @Override
    public String getProperty(String key) {
        // read configFile
        if (ConfigInf.F_LENGTH == key) {
            return value;
        } else {
            return "100";
        }

    }

    public void update() {
        value = "100";
    }

}

AreaCalculatorWithConfig(lib side)

public class AreaCalculatorWithConfig {
    private int length = 10;
    private int width = 10;
    //
    private static final AreaCalculatorWithConfig areaCalculator = new AreaCalculatorWithConfig();

    private AreaCalculatorWithConfig() {
        // TODO Auto-generated constructor stub
    }

    public static AreaCalculatorWithConfig getInstance() {
        return areaCalculator;
    }

    public int calculateArea() {
        ConfigInf config = ConfigFactory.getConfig();
        length = getInt(config.getProperty(ConfigInf.F_LENGTH));
        width = getInt(config.getProperty(ConfigInf.F_WIDTH));
        return length * width;
    }

    public static int getInt(String value) {
        return Integer.parseInt(value);
    }
}

TestMainWithConfig(客户端)

public class TestMainWithConfig {
    public static void main(String[] args) {
        // init;
        ClientConfig config = new ClientConfig();
        ConfigFactory.init(config);
        //
        System.out.println("Before update:"
                + AreaCalculatorWithConfig.getInstance().calculateArea());
        config.update();
        System.out.println("After update:"
                + AreaCalculatorWithConfig.getInstance().calculateArea());
    }
}

答案 3 :(得分:0)

根据您的要求,您可以使用Factory pattern创建库实例,该实例基于传递的常量Singleton来创建实例。

答案 4 :(得分:0)

我只是将初始化添加到Config类,在那里可以可靠地初始化一次。然后,应用程序的其余部分依赖于正确完成初始化。也许您可能希望避免异常重复初始化。诀窍在于确保只有一个点可以通过设计或异常的强力来填充单例。日志记录的配置非常相似。虽然,这并不奇怪。

答案 5 :(得分:0)

您尝试创建的库完全违反面向对象设计的原则。您不应该创建函数/方法库。相反,你应该创建一个包含状态和行为的类库。