2013-06-30 22 views
0

目前我有這種設置:Java的泛型類型參數使用關係

public class AccountManager extends Manager<AccountBean, AccountConstraint> { } 

public class AccountBean implements Bean { } 

public class AccountConstraint extends AbstractConstraint { } 

一個幾句話:

public abstract class Manager<B extends Bean, C extends AbstractConstraint> { 
    public final int insert(B b); 

    public final boolean update(B b); 

    public final boolean delete(B b); 

    public final B get(C... c); 

    public final List<B> search(C... c); 

    public final List<B> getAll(); 
} 

public interface Bean { } 

public abstract class AbstractConstraint { } 

在具體使用

  • Bean是最低的實體可能。這是數據庫中表的一行的直接實例。
  • AbstractConstraint的具體實現不應該實現/擴展Bean的具體實現,除非我在這裏弄錯了。

通過Manager我可以肯定,你可以通過的是一個具體的版本<Bean, AbstractConstraint>

但是目前它是完全有效的定義是:

public class BogusManager extends Manager<AccountBean, CharacterConstraint> { } 

這是沒有意義的,我怎麼能限制,使得這是不允許的了的代碼?

我認爲,我有兩個選擇:

1)改變AccountConstraintAccountConstraint<AccountBean>,但我不認爲這將是有效的,因爲類型參數將不會在AccountConstraint使用本身。

2)有一種方法來定義的關係R,讓Manager檢查,如果<B, C>是關係R,換句話說,你需要檢查R(B, C)。但是你還需要能夠定義一個關係R<AccountBean, AccountConstraint>然後,這將意味着R = Manager,但我不認爲它可能是真實的。無論如何,如果這是真的,我將如何能夠實現這一點?

問候。

+0

如果約束從不使用它們約束的類型,爲什麼它們與它們有關?也就是說,爲什麼'Manager '沒有任何意義,但是'Manager '卻沒有意義,儘管這些約束似乎沒有做特定於bean的任何事情? – millimoose

+1

或者換一種說法:也許平行班的層次結構是你應該擺脫的設計氣味,如果它們之間甚至沒有強的耦合。 – millimoose

+0

'AccountConstraint'確實限制了'AccountBean',所以我認爲設計缺陷在那裏。儘管我在'AccountConstraint'本身看不到類型參數。 – skiwi

回答

1

你的第一個選擇是合法的,你不需要使用類型變量。

對於第二個選項,您需要將beanconstraint的類實例傳遞給管理器構造函數,該構造函數將檢查這是否是合法對。據我所知,沒有辦法只在源代碼中實現這種檢查,即向源代碼添加聲明性約束。

1

像這樣的事情應該滿足選項2的編譯時版本:

interface Witness< B, C > {} 

public final class AccountConstraintsForAccountsOnly implements Witness< AccountBean, AccountConstraint > {} 
public final class CharacterConstraintsForCharactersOnly implements Witness< CharacterBean, CharacterConstraint > {} 

public abstract class Manager< B extends Bean, C extends AbstractConstraint, W extends Witness< B, C > { ... } 
0

對於選項1

//add a Type  
abstract class AbstractConstraint<T>{} 
//Type is tied to your Concrete bean 
abstract class Manager<B extends Bean, C extends AbstractConstraint<B> > 
{ 
. 
. 
. 
} 

雖然實施Constraint,說明它是什麼類型的Constraint,僅通過通過Bean類型

Ex。

class BogusBean implements Bean { } 
class BogusConstraint extends AbstractConstraint<BogusBean> { } 
class BogusManager extends Manager<BogusBean, BogusConstraint> {} 
+0

我相信這是OP –

+0

中的選項1 @JudgeMental是 – Niranjan