2016-08-25 15 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; 
} 

BarServiceBazServiceBazTypeAServiceBazTypeBServiceなどの名前付けスキームを持ち、同様の名前付けスキームを持ち、すべて自分が担当するクラスを返すメソッドを持っています。List<class they are responsible for>。次に、これらのメソッドはそれぞれ、特定のメソッドメソッドに渡されるパラメータに基づく基準を使用して、シグニチャGetObjects(Class Viewtype, Class BeanType, Criteria)を持つBaseServiceからメソッドを呼び出します。 Beanはサービスレイヤーとデータアクセスレイヤーの間にあり、実際には関係ありません。

スキームの例:上記

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がRaw Listを返すため、多くのEclipseの警告とコードが読みにくくなることです。このプロジェクトの警告の2/3以上は生の型の使用に関するものですが、コードはまだコンパイルされていますが、それはたくさんのメッセージです。

拡張クラスを拡張する2番目の種類のViewがない場合は、List<? extends Fooview>を実行できますが、これはBazViewを拡張するクラスにエラーをもたらします。あなたは両方を持っているときジェネリック型をここで動作させる方法はありますか? Baseviewと?拡張XはBaseviewを拡張しますか?

BaseServiceクラス:

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

と、特定のサービスで

+0

@AxelH問題は、私たちがサービス内で時々別のビューを返すということです。たとえば、BarServiceには、BazTypeA型のリストを返すGetConnectedBazTypeAs()メソッドがあります。 – Nzall

+0

もちろん、サービスごとに、ジェネリックタイプを正しいタイプのビューに設定する必要があります。 – AxelH

+0

ここで私はもう少し答えを説明します – AxelH

答えて

0

私が正しくあなたを理解していれば、あなたが必要なものは、あなたのBaseServicegetObject方法で使用される一般的な型を取得することです:

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

あなたはリストを話していますが、これはあなたにはありません。あなたの例は明確ではありません、ベース***クラス/インターフェイスは何ですか? – AxelH

+0

基本ビューの内容と、ビューの一覧の取得方法を明確にするために更新されました。 – Nzall

2

私の答えは、私はあなたのBaseServiceがインタフェースであると思うことを除いて、他の人からあまり違いはありません。

私たちのサービスレイヤでは、サービスメソッドが実装されています。 BaseS ervice

私はそのようなインターフェース(EDIT)を定義します:抽象クラスでそのインターフェイスを実装する

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){} 
} 

EDIT) すべてのサービスの実装は、まっすぐでなければなりません。すべてがきれいにタイプされているので

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

注:

インターフェイスを抽象クラス(可能な場合)に置き換えると、両方のサンプルメソッドが抽象クラスで実装できるため、コードが再び減少します。主な方法は全く変更する必要はありません。あなたは、あなたのオブジェクトを作成し、そのレベルでもジェネリックを使用する必要が

EDIT

。そうでなければ、たくさんのキャスティングが必要になり、リストでそれらの醜い警告を得るでしょう。私はあなたのために私のサンプルを更新しました。

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

関連する問題