我正在尝试创建一个API,以便在其他程序员使用我的服务时不需要实现和类名。该服务对“项目”执行各种操作,但服务应如何处理项目请求的主要因素是基于用户类型。到目前为止,我有一个接口(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
?
干杯,
Alexei Blue。
所有这一切的一般想法是,当发明另一个用户类型时,如果需要,可以添加另一个用户特定服务,保持现有代码不变。而且,如果有很多用户类型,我只希望使用API的人必须记住使用ItemService
,并让泛型来完成剩下的工作。
答案 0 :(得分:4)
你需要使用 abstract factory pattern. 简而言之,你需要一个知道所有可能的ItemService
子类的静态方法,给定Item
object或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);
}
答案 1 :(得分:0)
代码工作正常。您创建ItemService的实例:
Item item = new ItemService<Company>(company);
如果调用了ItemService的belongsToUser()方法,则会调用它。 您应该创建CompanyItemService的实例来调用它。