java - 当您有一堆极其相似且无法共享接口(interface)的类时,应该使用什么正确的设计模式?

标签 java design-patterns

我有一个名为Base的抽象类,它处理一堆逻辑来处理我拥有的一些数据。 API 如下所示:

// Class has no abstract methods, but is uninstantiable
public abstract class Base {
    private Param param;

    protected Base() {}

    protected void setParam(Param param) {
        this.param = param
    }

    public void doThing() {
        // Code here to do a common thing
    }

    public void doOtherThing() {
        // Code here to do another common thing
    }

    protected void handle(Object... objects) {
        // This code delegates work to a scripting language via the param 
        // It is not type safe and the array of objects needed will vary depending 
        // on the implementing class.
    }
}

当然,这里奇怪的是handle(Objects...)方法。要展示它的使用方式,请查看其中一个子类:

public class Person extends Base {
    protected Person(Param param) {
        super();
        setParam(param);
    }

    public void handle(String name, int age) {
        // Expose a type safe interface to the world
        super.handle(name, age);
    }
}

正如您所看到的,子类隐藏了 super.handle,它对于某些参数是 protected ,以便此类的使用者可以进行类型安全的交互,而无需传递对象数组。问题是,我想从一个强制每个参数有一个子类实例的工厂创建它们。目前,这个工厂看起来像这样:

public class Factory {
    Map<Param, Person> persons;
    Map<Param, Other> others; // Other also extends Base

    public Person getPerson(Param param) {
        Person person = persons.get(param);

        if (person == null) {
            person = new Person(param);
            persons.put(param, person);
        }

        return person;
    }

    public Other getOther(Param param) {
        Other other = others.get(param);

        if (other == null) {
            other = new Other(param);
            other.put(param, other);
        }

        return other;
    }
}

显然,这很糟糕,但我想不出更好的方法来处理这种情况,因为通过参数与脚本语言交互的奇怪性质,它依赖于字符串构造来执行代码。有人对如何清理这个设计有任何指导吗?

最佳答案

可以使用一些泛型和反射来概括工厂类,以便在运行时实例化特定的子类类型:

import java.util.HashMap;
import java.util.Map;

public class Factory<T> {

    private Map<Param, T> instances = new HashMap<Param, T>();

    public final T create(Class<T> clazz, Param param) throws Exception {
        T cur = instances.get(param);

        if (cur == null) {
             cur = clazz.newInstance();
             ((Base)cur).setParam(param);
             instances.put(param, cur);
        }
        return cur;
    }
}

子类应该有无参数构造函数,而不是公共(public)的;为了保持一致性,删除 with-param 1:

public class Person extends Base {

    protected Person(){}

    public void handle(String name, int age) {
        // Expose a type safe interface to the world
        super.handle(name, age);
    }

}

使用示例:

public class TestFactory {
    public static void main(String[] args) throws Exception {
        Factory<Person> factory = new Factory<Person>();
        Person p = factory.create(Person.class, new Param());
    }
}

当然,我知道这不是一种模式,也不是我可以引以为豪的更优雅的代码,但仍然避免了您必须为每个新子类更改工厂,它不使用静态方法并在单点中保留缓存逻辑。

关于java - 当您有一堆极其相似且无法共享接口(interface)的类时,应该使用什么正确的设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22122045/

相关文章:

java - 当用户通过 Vaadin 7 应用程序中的 FieldGroup 和 BeanContainer 编辑 bean 时,bean 内部所做的数据更改会消失

java - 从Java抽象类继承后访问属性

design-patterns - 在信用交易系统上实现事件溯源

java - 在 Java 中可观察

design-patterns - 你听说过 "Position"设计模式吗?

c# - 此代码片段是否使用 Repository 或 Adapter 模式?

java - 在调用父类(super class)型构造函数之前无法引用 PublicationDate

java - Synthetica Swing 它们无法正确加载

java - 将大量小文件读入内存的最快方法是什么?

c# - 循环依赖解决方案