簡體   English   中英

用於隱藏類型特定實現的Java泛型?

[英]Java generics for hiding type specific implementation?

我正在嘗試創建一個API,以便在其他程序員使用我的服務時不需要實現和類名。 服務在“項目”上執行各種操作,但是影響服務應如何處理項目請求的主要因素是基於用戶類型。 到目前為止,我有一個Interface( Item )和一個實現服務( ItemService ),然后是幾個由此擴展的用戶類型類(例如CompanyItemService )。 用戶類型還具有一個結構,其超類為User ,子類為Company

public class ItemService<T extends User> extends Item {
    User user;
    public ItemService(User user) {
        this.user = user;
    }

    @Override
    public boolean belongsToUser() {
        //Check all records
    }
}

public class CompanyItemService<T extends Company> extends ItemService<Company> {
    public CompanyItemService(Company user) {
        super(user);
    }

    @Override
    public boolean belongsToUser() {
        //Check company specific records
    }
}

public class User {
    //Common user stuff
}

public class Company extends User {
    //Company specific stuff
}

因此,我希望能夠通過以下電話使用我的服務:

User company = new Company();
//stuff
Item item = new ItemService<Company>(company)
item.belongsToUser();

但是,當我這樣做時,將調用ItemService的方法,而不是CompanyItemService中的重寫方法。 是否有可能在不需要知道它屬於CompanyItemService類的情況下獲取此重寫方法?

干杯,

阿列克謝藍。

這一切的總體思路是,當發明了另一種用戶類型時,可以根據需要添加另一種特定於用戶的服務,而無需更改現有代碼。 而且,如果有很多用戶類型,我只希望使用API​​的人必須記住使用ItemService而讓泛型執行其余操作。

您需要使用抽象工廠模式。 簡而言之,您需要一個靜態方法來了解所有可能的ItemService子類,並且在給定Item對象或Class作為User的子類的情況下,返回正確ItemService子類的實例。 換句話說,類似

public static ItemService<?> instance(Class<? extends User> c) {
    if (c == Customer.class)
        return new CustomerItemService();
    else if (c == Employee.class)
        return new EmployeeItemService();
    ...
}

那你可以說

ItemService<?> service = ItemService.instance(Customer.class);

或者,您可以構建地圖:

Map<Class<? extends User>, Class<? extends ItemService>> services = 
    new HashMap<Class<? extends User>, Class<? extends ItemService>>() {{
    put(Customer.class, CustomerItemService.class);
    put(Employee.class, EmployeeItemService.class);
    // more...
}};

然后instance()可能看起來像

ItemService<? extends User> instance(Class<? extends User> c) {
    return services.get(c);
}

代碼可以正常工作。 您創建ItemService的實例:

Item item = new ItemService<Company>(company);

如果調用,則將調用ItemService的方法。 您應該創建CompanyItemService的實例以調用該方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM