【问题标题】:Suitable design using Generics with Wildcard使用泛型和通配符的合适设计
【发布时间】:2012-03-13 01:13:52
【问题描述】:

我正在尝试确定泛型是否能够帮助我设计更好且可扩展的解决方案。在我的应用程序中,有一个模型类负责从数据源加载数据,我使用 ModelProxy 类来公开 Model 类中的一些方法。

public interface ModelProxy {
     public int getOrderCount();
     public int getCustomerCount();
}

public abstract class AbstractModel {
     public abstract ModelProxy loadData(Configuration configuration);
}

public class ConcreteModel extends AbstractModel {
    public ModelProxy loadData(Configuration configuration) {
         loadInternal();
         return new ConcereteModelProxy(this);
    }
}

到目前为止一切看起来都不错,但我想看看泛型(带有通配符)是否可以帮助我设计一个更好的解决方案,允许扩展 ModelProxy 接口或 Configuration 类。例如,在另一个具体模型类中,我想使用 ExtendedConfiguration 类和 ExtendedModelProxy。

public ExtendedModelProxy extends ModelProxy {
   // Additional methods
   public int getTotalCount();
}

public class ConcereteModel2 extends AbstractModel {
   public ExtendedModelProxy loadDate(ExtendedConfiguration configuration) {
      return new ConcreteExtendedModelProxy(this);
   }
}

Java 泛型会帮助我实现上述目标吗? 或者也许我的设计有缺陷,我需要重新设计它。任何建议都会非常有帮助。

谢谢,

示例客户端代码:

public abstract class Service {
   public ModelProxy load(Configuration configuration) {
       return getModel().loadData(configuration);
   }

   protected abstract AbstractModel getModel();
}

public class ServiceImpl extends Service {
   protected AbstractModel getModel() {
      return new ConcreteModel();
   }

   public static void main() {
      Service service = new ServiceImpl();
      ModelProxy proxy = service.load(configuration);
      System.out.println(proxy.getOrderCount());
   }
}

public class ExtendedServiceImpl extends Service {
   protected AbstractModel getModel() {
      return new ConcreteModel2();
   }

   public static void main() {
      Service service = new ExtendedServiceImpl();
      ExtendedModelProxy proxy = (ExtendedModelProxy) service.load(configuration);
      System.out.println(proxy.getTotalCount());
   }
}

我希望不要混淆太多。在 ExtendedServiceImpl 中,您可以看到我需要将 ModelProxy 转换为 ExtendedModelProxy 才能访问方法 getTotalCount。我的想法是也许我可以使用泛型来避免强制转换。类似的东西

public abstract <M extends ModelProxy, C extends Configuration> M loadData(C configuration);

也许我把事情复杂化了,我目前的设计确实是我所需要的。不确定...

【问题讨论】:

  • 我不清楚您要如何以及为什么要使用泛型。您能否发布一个SSCCE,其中包含您想要工作的最少代码?
  • 这些扩展类是否必须向客户端公开非扩展类中不存在的方法?从我现在看到的情况来看,使用接口会更好。
  • @Bohemian。刚刚添加了一些示例代码来展示我打算如何使用它。
  • @trutheality 我不打算公开我的模型类,但需要公开 ModelProxy 对象。我添加了一些代码来展示我打算如何使用它。 ServiceImpl 和 ExtendedServiceImpl 类。

标签: java generics polymorphism java-6


【解决方案1】:

这种东西怎么样

package jj;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.*;

interface Configuration {
}

interface Model {
}

interface OrderModel extends Model {
    public int getOrderCount();
    public int getCustomerCount();
}

interface CustomerModel extends Model {
    public int getName();
    public int getAddress();
}

abstract class AbstractModel<M extends Model> {
    @SuppressWarnings("unchecked")
    public M loadData(Configuration configuration) {
        // connect to stuff
        Object connection = null;
        loadInternal(configuration, connection);
        // do some other stuff
        return (M) Proxy.newProxyInstance(null, new Class<?>[]{getModelClass()}, null);
    }

    protected abstract void loadInternal(Configuration configuration,
            Object connection);

    protected abstract InvocationHandler getInvocationHandler(Object connection);
    protected abstract Class<M> getModelClass();
}

class ConcreteOrderModel extends AbstractModel<OrderModel> {
    public void loadInternal(Configuration configuration,
            Object connection) {
    }

    protected InvocationHandler getInvocationHandler(Object connection) {
        return null;
    }

    protected Class<OrderModel> getModelClass() {
        return OrderModel.class;
    }
}

class ConcreteCustomerModel extends AbstractModel<CustomerModel> {
    public void loadInternal(Configuration configuration,
            Object connection) {
    }

    protected InvocationHandler getInvocationHandler(Object connection) {
        return null;
    }

    protected Class<CustomerModel> getModelClass() {
        return CustomerModel.class;
    }
}

【讨论】:

    猜你喜欢
    • 2012-10-31
    • 2011-11-12
    • 1970-01-01
    • 2017-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    相关资源
    最近更新 更多