我正在尝试创建一个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,而让泛型执行其余操作。

最佳答案

您需要使用abstract factory pattern.简而言之,您需要在某个地方使用静态方法来知道所有可能的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);
}

09-04 07:19