Java OO Design帮助 - 如何抽象出一个save方法?

Ste*_*ier 3 java oop design-patterns

我有一个Preference类(模块),用于几个不同的应用程序.基本上它是首选项的缓存,因此系统不必一直调用后端.它类似于缓存,但有一些额外的细节,如isPreferenceSelected,有一些辅助方法等.

问题是我想在类中包含一个savePreference,以便任何使用它的人都可以覆盖该方法,无论是数据库,平面文件等等.关键是这个模块不想要照顾.问题是它不是一个抽象类,所以我不能覆盖静态方法,即使它是,我也不想创建一百万个实例,因为我不想每次都加载首选项.我也不能创建一个抽象的单例.

因此我不知道该怎么做.这是我想要评论的代码片段:

// Please ignore the missing Generics, etc.
public class Preference
{
  private static HashMap preferences = new HashMap();

  public static ... 

  // Some preferences are objects, such as images, etc.
  public static setPreference(String name, Object value)
  {
    .. some helper code
    preferences.put(name, value); // ignoring issues with if it already exists ;)
    savePreference(name, value); // saves to database, flatfile, etc.
  }
}
Run Code Online (Sandbox Code Playgroud)

这是不同系统利用的核心类/代码.现在我想做的是在webapp,桌面应用程序等中说,能够在我的代码中使用这个类,例如:

public someFunction(...)
{
  .. do some cool code
  Preference.savePreference("logoImage", image);
}
Run Code Online (Sandbox Code Playgroud)

并且该savePreference()方法不仅可以保存内存中的首选项,还可以将其保存到外部源.否则我无处不在,我必须savePreference()通过db调用savePreferenceToDB(),FlatFile调用,例如savePreferenceToFlatFile(),等等来跟随它.这非常容易出错,有人会忘记保存它.另外,使用这种类型的代码将保存洒到任何地方的永久存储代码真的没有意义,因为它应该只执行一次.还要记住,主模块不知道永久存储是数据库,xml文件,平面文件等.

提示:如果我这样做Preference.getInstance().savePreference()不行,因为你不能抽象单身.而且我无法创建静态方法savePreference(),因为它无法覆盖静态方法.

我能看到的唯一选择是创建某种复杂的Factory模式,但这对我来说似乎有点过分.因此,我们将非常感谢任何建议.

mpo*_*llo 7

这听起来像是您的依赖注入(DI)容器应该处理的东西,而不是复杂的工厂模式.

也就是说,我认为你应该放弃使用static,有任何创建其他应用程序注入Preference您的应用程序的实例.你可以在没有DI框架的情况下做到这一点,如果你只是Preference在构造函数中作为参数来获取依赖它的任何其他类.


编辑:让我举一个没有框架的依赖注入的例子.参加以下课程:

public class Preference
{
    private String userName;

    public Preference(String userName)
    {
        this.userName = userName;
    }

    public void savePreference()
    {
        // Default implementation saves it to the screen. ;-)
       System.out.println(userName);
    }
}

public class Foo
{
    private Preference p;

    public Foo(Preference p)
    {
        this.p = p;
    }
}

public class Bar
{
    private Preference p;

    public Bar(Preference p)
    {
        this.p = p;
    }
}

public class Main
{
    public static void main(String[] args)
    {
        Preference p = new Preference("Mike");

        Foo f = new Foo(p);
        Bar b = new Bar(p);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一个简单的例子,但它满足您的要求:

  • Preference实例仅创建一次
  • Preference班可谁实现了扩展Main该类实例什么样的Preference,他们希望子类,如果他们想坚持它在关系数据库(或其他)

通过避免首先进行static调用,您还可以对您的someFunction()示例进行单元测试,而无需引入潜在的大型复杂偏好框架.相反,有人实现了一个模拟Preference子类并将其传递给运行的类someFunction().您的代码将以这种方式更加可测试.

  • +1不要通过引入静态方法的*major*问题来解决如何共享单个'Preference`实例的*minor*问题. (2认同)