Java 使用泛型<;K>;减少重复代码?
我有下面的代码。正如你们所看到的,我正在执行类似的逻辑,但一次用于自行车,一次用于汽车。我可以使用Java 使用泛型<;K>;减少重复代码?,java,oop,generics,inheritance,Java,Oop,Generics,Inheritance,我有下面的代码。正如你们所看到的,我正在执行类似的逻辑,但一次用于自行车,一次用于汽车。我可以使用来减少重复的代码吗?我没有使用,因此我不确定在何处以及如何将其合并。在哪里可以决定是调用getCarsWithFeature还是getBikesWithFeature 减少行数(可能会降低可读性)或使用类似的重复代码是最佳做法吗 public Set<Car> getPremiumCars(String filter) { final Callable<Set<Car
来减少重复的代码吗?我没有使用
,因此我不确定在何处以及如何将其合并。在哪里可以决定是调用getCarsWithFeature
还是getBikesWithFeature
减少行数(可能会降低可读性)或使用类似的重复代码是最佳做法吗
public Set<Car> getPremiumCars(String filter) {
final Callable<Set<Car>> retryGetCars = new RetryingCallable<>(retryStrategy(), getCars(filter));
return retryGetCars.call();
}
public Callable<Set<Car>> getCars(String feature) {
return new Callable<Set<Car>>() {
@Override
public Set<Car> call() throws Exception {
Set<Car> cars = getCarsWithFeature(feature);
return Collections.unmodifiableSet(cars);
}
};
}
public Set<Bike> getPremiumBikes(String filter) {
final Callable<Set<Bike>> retryGetBikes = new RetryingCallable<>(retryStrategy(), getBikes(filter));
return retryGetBikes.call();
}
public Callable<Set<Bike>> getBikes(String feature) {
return new Callable<Set<Bike>>() {
@Override
public Set<Bike> call() throws Exception {
Set<Bike> bikes = getBikesWithFeature(feature);
return Collections.unmodifiableSet(bikes);
}
};
}
public Set getPremiumCars(字符串过滤器){
final Callable retryGetCars=new RetryingCallable(retryStrategy(),getCars(filter));
return retryGetCars.call();
}
公共可调用getCars(字符串功能){
返回新的可调用(){
@凌驾
public Set call()引发异常{
设置车辆=getCarsWithFeature(特征);
返回集合。不可修改集合(cars);
}
};
}
公共集getPremiumBikes(字符串筛选器){
final Callable retryGetBikes=new RetryingCallable(retryStrategy(),getBikes(filter));
return retryGetBikes.call();
}
公共可调用getBikes(字符串特性){
返回新的可调用(){
@凌驾
public Set call()引发异常{
设置bikes=getBikesWithFeature(feature);
返回集合。不可修改集合(自行车);
}
};
}
创建Car和Bike的基类,然后将通用方法放在那里。
然后将汽车和自行车从中伸出。使用基类更新公共方法。下面给出了实施的示例提示:
class Vehicle {
public Set<Vehicle> getWithFilter(String filter) {
final Callable<Set<Vehicle>> retryGet = new RetryingCallable<>(retryStrategy(), get(filter));
return retryGet.call();
}
public Callable<Set<Vehicle>> getWithFeature(String feature) {
return new Callable<Set<Vehicle>>() {
public Set<Vehicle> call() throws Exception {
Set<Vehicle> vehicles = getWithFeature(feature);
return Collections.unmodifiableSet(vehicles);
}
};
}
}
class Car extends Vehicle {
}
class Bike extends Vehicle {
}
我不知道您的全部代码,但我建议这两个类实现相同的接口-比方说
车辆
:
public interface Vehicle {
}
然后,您可以编写最近可以重用的代码:
public <T extends Vehicle> Set<T> getPremiumVehicle(Function<String, Callable<Set<T>>> vehicleSupplier, String filter) throws Exception {
final Callable<Set<T>> retryGetCars = new RetryingCallable<T>(retryStrategy(), vehicleSupplier.apply(filter));
return retryGetCars.call();
}
public <T extends Vehicle> Callable<Set<T>> getVehicle(Function<String, Set<T>> vehicleSupplier, String feature) {
return () -> {
Set<T> vehicles = vehicleSupplier.apply(feature);
return Collections.unmodifiableSet(vehicles);
};
}
public Set getPremiumVehicle(函数vehicleSupplier,字符串过滤器)引发异常{
final Callable retryGetCars=新的RetryingCallable(retryStrategy(),Vehicles Supplier.apply(filter));
return retryGetCars.call();
}
公共可调用getVehicle(功能车辆供应商,字符串功能){
返回()->{
设置车辆=车辆供应商。应用(功能);
返回集合。不可修改集合(车辆);
};
}
现在,您可以重用上述代码,如:
public Set<Car> getPremiumCars(String filter) throws Exception {
return getPremiumVehicle(this::getCars, filter);
}
public Set<Bike> getPremiumBikes(String filter) throws Exception {
return getPremiumVehicle(this::getBikes, filter);
}
public Callable<Set<Car>> getCars(String feature) {
return getVehicle(this::getCarsWithFeature, feature);
}
public Callable<Set<Bike>> getBikes(String feature) {
return getVehicle(this::getBikesWithFeature, feature);
}
公共集getPremiumCars(字符串筛选器)引发异常{
返回getPremiumVehicle(this::getCars,filter);
}
公共集getPremiumBikes(字符串筛选器)引发异常{
返回getPremiumVehicle(this::getBikes,filter);
}
公共可调用getCars(字符串功能){
返回getVehicle(此::getCarsWithFeature,feature);
}
公共可调用getBikes(字符串特性){
返回getVehicle(此::getBikesWithFeature,feature);
}
是的,如果您对汽车和自行车都有一个通用(基类)类型,您可以这样做。但是,汽车和自行车的类型完全不同,我想您会在使用泛型时遇到麻烦。最好将所有通用代码都分解成一个抽象基类,因为这样仍然可以让您专门化自行车或汽车子类的任何代码需求。这个问题的答案应该是getCarsWithFeature
和getBikesWithFeature
。无论是否使用仿制药,它们似乎都是不同的调用。谢谢@Piro。是的,他们确实是不同的电话。在这种情况下不可能使用泛型吗?为什么代码中充斥着Callables
和其他不相关的东西?既然你在基本代码方面遇到了问题,你应该坚持使用基本代码,而不是无缘无故地让它看起来“高级”。谢谢你的回答。正如@Piro在上面的评论中提到的,有两个不同的调用getCarsWithFeature
和getBikesWithFeature
。即使有一个基类,那部分代码仍然必须存在。你认为我能转到基础课的哪一部分?谢谢你的回答。我要试一试。但是,如果我没有汽车和自行车,而是上完全不相关的课呢?在这种情况下,我不能有一个基类。在这种情况下,建议是什么?在这种情况下,您必须使用通用模板或Java对象类,然后转换到适当的类。是的,这也是我的想法。所以我的问题是关于泛型。我不能使用基类方法。让我们来。
public Set<Car> getPremiumCars(String filter) throws Exception {
return getPremiumVehicle(this::getCars, filter);
}
public Set<Bike> getPremiumBikes(String filter) throws Exception {
return getPremiumVehicle(this::getBikes, filter);
}
public Callable<Set<Car>> getCars(String feature) {
return getVehicle(this::getCarsWithFeature, feature);
}
public Callable<Set<Bike>> getBikes(String feature) {
return getVehicle(this::getBikesWithFeature, feature);
}