2012-03-13 42 views
1

我想确定泛型是否能够帮助我设计更好的可扩展解决方案。在我的应用程序中,有一个模型类负责从数据源加载数据,我使用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接口或配置类。例如,在另一个具体模型类中,我希望使用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); 

也许我是过于复杂的事情,真的是我目前的设计是我需要的。不知道......

+0

我不如何​​,以及为什么要使用泛型清楚。你可以发布一个[SSCCE](http://pscode.org/sscce.html),它有你想要的最小代码吗? – Bohemian 2012-03-13 01:36:55

+0

这些扩展类是否必须向客户公开未在非扩展对象中存在的方法?从我看到的现在看来,它会更好地使用接口。 – trutheality 2012-03-13 01:43:14

+0

@波希米亚。只需添加一些示例代码以显示我打算如何使用它。 – user320587 2012-03-13 03:12:23

回答

0

怎么这种事情

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; 
    } 
}