2016-08-25 40 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

相關問題