用于策略的Java泛型,作为在构造函数中传递策略的替代方法

时间:2009-04-01 12:48:08

标签: java generics

我有一些类似的Java代码:

public class Thing {

    private IPolicy policy;

    public Thing(IPolicy policy) {
            this.policy = policy;
    }

    public void doSomething() {
            this.policy.execute();
    }   
}

我的问题是:是否可以使用泛型而不是将策略传递给构造函数?我想这意味着我希望它最终成为

public class Thing<T extends IPolicy>

但我不是那样做泛型。

我的动机是:1)我的程序更适合我的程序,因为它是类型的一部分而不是参与构造函数(还有其他更相关的事情要做)和2)我是试图学习泛型。

3 个答案:

答案 0 :(得分:3)

我认为这没有多大意义。是不是您依赖的政策本身,而不仅仅是政策的类型?您是否想要询问政策问题(例如是否允许采取行动)?这意味着你需要一个策略实例 - 这意味着将它传递给构造函数是有意义的。

当您需要强类型API时,泛型是合适的,其中API的一部分依赖于另一种类型,但实现本身并不关心类型是什么(可能有一些约束)。集合API可能是规范示例 - List<T>并不关心T是什么,而是希望根据T 公开强类型API 。我看不出这符合你的政策范例。

答案 1 :(得分:0)

你要做的是确保一件事总是有一个政策,即。一项政策不能存在。这只需要构造函数机制或抽象,如

public abstract class Thing {
   public abstract Policy getPolicy();
   public void doSomething() {
       getPolicy().execute();
   }
}

答案 2 :(得分:0)

即使是通用版本也不会避免“将策略传递给构造函数”,因为Java泛型使用类型擦除。但是,您可以实现GenericThing(Class<T> clazz)构造函数,但 overkill

public class GenericThing<T extends IPolicy> {

    private T policy;

    public GenericThing(Class<T> clazz) throws InstantiationException, IllegalAccessException {
        policy = clazz.newInstance();
    }

    public GenericThing(T policy) {
        this.policy = policy;
    }

    public void doSomething() {
        this.policy.execute();
    }
}

我非常同意Jon的answer。你并没有真正利用强类型