【问题标题】:Java generics for policy as alternative to passing policy in constructor用于策略的 Java 泛型作为在构造函数中传递策略的替代方案
【发布时间】:2009-04-01 12:48:08
【问题描述】:

我有一些类似的 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)我尝试学习泛型。

【问题讨论】:

  • 你来自 C++ 吗? (Java 泛型不是 C++ 模板。)在 Java 中,您通常使用沼泽标准 [动态] 多态性来描述行为,使用泛型来描述参数化类型。可能有必要将两者结合起来,而 C++ 可能会单独使用模板。

标签: java generics


【解决方案1】:

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

泛型适用于您想要一个强类型 API,其中部分 API 依赖于另一种类型,但实现本身并不关心类型是什么(可能有一些限制)。集合 API 可能是典型的例子 - List&lt;T&gt; 不关心 T 是什么,但希望在 T 方面公开一个强类型 API。我看不出这与您的政策示例相符。

【讨论】:

    【解决方案2】:

    您要做的是确保事物始终具有策略,即。事物不能与策略一起存在。这仅需要构造函数机制或抽象,例如,

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

    【讨论】:

      【解决方案3】:

      即使是泛型版本也无法避免“将策略传递给构造函数”,因为 Java 泛型使用类型擦除。但是,您可以实现 GenericThing(Class&lt;T&gt; clazz) 构造函数,但这是矫枉过正:

      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。您并没有真正利用 强类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-21
        • 2018-06-06
        • 2020-08-09
        • 2013-05-23
        • 1970-01-01
        • 1970-01-01
        • 2013-08-31
        相关资源
        最近更新 更多