2016-08-25 88 views
0

在我们当前的代码库,我们有如下数据结构我们的服务层,我们的前端层之间进行通信:如何让一个类扩展另一个扩展类与泛型集合的工作?

public class BaseView { 
    private Integer id; 
    // Other common attributes and getters/setters; 
} 

public class BarView extends BaseView { 
    private String name; 
    private String Description; 
    // Other attributes for this object and getters/setters; 
} 

我们也有一些双扩展类:

public class BazView extends BaseView { 
    // name, description, other common attributes; 
} 

public class BazTypeAView extends BazView { 
    // attributes specific to Type A Baz; 
} 

public class BazTypeBView extends BazView { 
    // attributes specific to Type B Baz; 
} 

我们服务层,我们有实现BaseService的服务方法:BarService,BazService,BazTypeAService,BazTypeBService和其他具有相似命名方案的方法,它们都有方法返回它们负责的类或者List<class they are responsible for>。反过来,这些方法中的每一个都会调用BaseService中的方法,其签名为GetObjects(Class Viewtype, Class BeanType, Criteria),其中基于参数的标准传递给特定的方法方法。 Beans位于服务层和数据访问层之间,与此无关。

的方案的例子:

public interface BaseService { 
    public BaseView getObject(Class viewType, class beanType, Integer id); 

    public List<BaseView> getObjects(Class viewType, class beanType, Criteria criteria); 
} 

public class BaseServiceImpl implements BaseService { 
    protected BaseView getObject(Class viewType, class beanType, Integer id){ 
     BaseBean bean = (BaseBean) DataService.getobject (beanType, id); 
     BaseView view = ViewGenerator.createEmptyView(viewType); 
     copyAttributes(bean, view); 
     return view; 
    } 

    protected List<BaseView> getObject(Class viewType, class beanType, Criteria criteria){ 
     List<BaseBean> bean = (List<BaseBean>) DataService.getobject (beanType, Criteria); 
     List<BaseView> view = new ArrayList<BaseView>(); 
     copyAttributes(bean, view); 
     return view; 
    } 
} 

public interface BarService extends BaseService { 
    public BarView getBar(Integer id); 

    public List<BarView> getBars(BarView barView); 
} 

public class BarServiceImpl extends BaseServiceImpl implements BarService { 
    public BarView getBar(Integer id){ 
     BarView bar = getObject(BarView.class, BarBean.class, id); 
     return bar; 
    } 

    public List<BarView> getBars(BarView barView){ 
     Criteria criteria = getCriteriaFromBarView(barView); 
     List<BarView> bars = getObjects(BarView.class, BarBean.class, criteria); 
     return bars; 
    } 
} 

以上是系统大致是如何工作的。创建酒吧,获取酒吧列表,更新酒吧并删除酒吧的方法都与上述内容完全相同。

问题是getObject返回一个原始列表,导致很多Eclipse警告和代码难以阅读。这个项目的2/3以上的警告都是关于原始类型的使用情况,尽管我们的代码仍然按照它应该编译和运行,但它是很多消息。

如果我们没有扩展扩展类的第二种视图,我们可以做List<? extends Fooview>,但是这会给扩展BazView的类带来错误。有两种方法可以让泛型类型在这里工作吗?扩展Baseview和?扩展X扩展Baseview?

+0

@AxelH问题是我们有时在我们的服务中有方法返回不同的视图。例如,BarService可能有一个方法GetConnectedBazTypeAs(),它返回一个BazTypeA类型的列表。 – Nzall

+0

关闭课程,但对于每个服务,您需要将通用类型设置为正确类型的视图。 – AxelH

+0

这里我在解答中多加一点解释 – AxelH

回答

0

如果我理解正确的话,你需要的是让你的BaseService获得了将在getObject方法使用泛型类型:

BaseService类:

public class <T extends FooView> BaseService<T> { 
    public T getObject() { 
    ... 
    } 
} 

,并在特定的服务:

public class BazTypeAService extends BaseService<BazTypeAView> { 
    ... 
} 
+0

我将如何将您的解决方案应用于我的情况(问题中已更新)? – Nzall

0

使用代码样式的快速回答,如果我没有很好理解,我会删除它。

尝试使用泛型类型是这样的:

public abstract class BarService<T extends FooView>{ 
    List<T> list; 
    ... 

    public List<T> getList(){ return list;} 
} 

public class BazService extends BarService<BazView>{ 
    ... 
} 

public class BazTypeBService extends BarService<BazTypeBView>{ 
    ... 
} 

... 

这里,

BazService.getList() will return a List<BazView> instance 
BazTypeBService .getList() will return a List<BazTypeBView> instance 
+0

我已经给出了一个关于我们的服务层如何在问题中大致起作用的基本例子,因为我对它的工作原理并不十分清楚。我不太清楚如何将您的示例应用于我的场景。 – Nzall

+0

你说的是list但是没有这个例子,你的例子不清楚,Base ***类/接口是什么。 – AxelH

+0

已更新,以澄清基本视图是什么以及它如何获取视图列表。 – Nzall

2

我的回答不会从别人太大的差别,但我猜你的BaseService是一个接口:

在我们的服务层,我们有服务方法实施一个BaseS ervice

我会这样定义的接口(编辑):

public interface BaseService<T extends FooView>{ 
    T getObject(Class<T> viewType, Class<? extends FooBean> beanType, Integer id);  
    List<T> getAllObjects(Class<T> viewType, Class<? extends FooBean> beanType); 
} 

ADDED) 要求所有根据服务使用仿制药,以及实现在一个抽象类,接口:

public abstract class BaseServiceImpl<T extends FooView> implements BaseService<T>{ 
    @Override 
    public T getObject(Class<T> viewType, Class<? extends FooBean> beanType, Integer id){ 
     FooBean bean = DataService.getObject(beanType, id); 
     T view = ViewGenerator.createEmptyView(viewType); 
     copyAttributes(bean, view); 

     return view; 
    } 

    @Override 
    public List<T> getAllObjects(Class<T> viewType, Class<? extends FooBean> beanType){ 
     List<? extends FooBean> beanList = DataService.getAllObjects(beanType); 

     return beanList.stream().map(bean -> { 
      T view = ViewGenerator.createEmptyView(viewType); 
      copyAttributes(bean, view); 
      return view; 
     }).collect(Collectors.toList()); 
    } 

    private void copyAttributes(FooBean bean, T view){} 
} 

编辑) 所有服务的实现应该是直截了当则:

public class BarServiceImpl extends BaseServiceImpl<BarView> implements BarService{ 

    @Override 
    public BarView getBar(Integer id){ 
     return getObject(BarView.class, BarBean.class, id); 
    } 

    @Override 
    public List<BarView> getAllBars(){ 
     return getAllObjects(BarView.class, BarBean.class); 
    } 
} 

public class BazServiceImpl extends BaseServiceImpl<BazView> implements BazService{ 
    @Override 
    public BazView getBaz(Integer id){ 
     return getObject(BazView.class, BazBean.class, id); 
    } 

    @Override 
    public List<BazView> getAllBazs(){ 
     return getAllObjects(BazView.class, BazBean.class); 
    } 
} 

public class BazTypeAServiceImpl extends BaseServiceImpl<BazTypeAView> implements BazTypeAService{ 
    @Override 
    public BazTypeAView getBazTypeA(Integer id){ 
     return getObject(BazTypeAView.class, BazTypeABean.class, id); 
    } 

    @Override 
    public List<BazTypeAView> getAllBazTypeAs(){ 
     return getAllObjects(BazTypeAView.class, BazTypeABean.class); 
    } 
} 

至少在我的主要方法有没有报警,因为一切都干净类型:

public class Main{ 
    public static void main(String[] args){ 
     BarService barService = new BarServiceImpl(); 
     BarView barView = barService.getBar(111); 
     List<BarView> barViewList = barService.getAllBars(); 

     BazService bazService = new BazServiceImpl(); 
     BazView bazView = bazService.getBaz(222); 
     List<BazView> bazViewList = bazService.getAllBazs(); 

     BazTypeAService bazTypeAService = new BazTypeAServiceImpl(); 
     BazTypeAView bazTypeAView = bazTypeAService.getBazTypeA(333); 
     List<BazTypeAView> bazTypeAViewList bazTypeAService.getAllBazTypeAs(); 
    } 
} 

注:

用抽象类替换接口(如果可能)将再次减少代码,因为这两个示例方法都可以在抽象类中实现。主要方法根本不需要改变。

编辑

您还需要使用泛型在您创建对象的水平。否则,您需要进行大量的演员表演,并且会在列表中看到这些丑陋的警告。我为你更新了我的样本。

EDIT2

我之前已经提到它,你的DataService的和你ViewGenerator需要使用泛型了。这是我将如何实现方法体:

public class DataService { 
    public static <T extends FooBean> T getObject(Class<T> beanType, Integer id){return null;}  
    public static <T extends FooBean> List<T> getAllObjects(Class<T> beanType){return null;} 
} 

public class ViewGenerator { 
    public static <T> T createEmptyView(Class<T> viewType){return null;} 
} 
+0

我已更新我的问题,并更清楚地解释了我的服务层。我将如何将您的解决方案应用于我的情况? – Nzall