我有三种通过字段过滤设备数组的方法。
public void filtrateByType(Device[] devices, String type) {
if (devices == null) {
return;
}
for (int i = 0; i < devices.length; i++) {
if (devices[i] == null) {
continue;
}
if (devices[i].getType() == null && type == null) {
continue;
} else if (devices[i].getType() == null) {
devices[i] = null;
continue;
}
if (!devices[i].getType().equals(type)) {
devices[i] = null;
}
}
}
其他方法类似。唯一的区别是调用另一个应用了过滤的字段的getter。例如,有一个呼叫
getModel()
而不是getType()
。这是否违反了DRY原理,我如何才能更改它,使其不(没有泛型)?附言
这是一项家庭作业,不幸的是我们还没有使用泛型。我也无法更改方法的签名。我有一个线索,我可以用一种方法创建内部类,该方法将调用所需的getter并返回一个值。因此,我需要将所有检查放入这种方法中,但是我真的不理解如何用我的逻辑(特别是使用“ continue”)来进行检查。
最佳答案
您可以创建一个如下所示的interface DeviceValueExtractor
:
@FunctionalInterface
public interface DeviceValueExtractor {
Object extractValue(Device device);
}
现在将您的方法重写为:
public void filterByType(Device[] devices, DeviceValueExtractor extractor, Object expect) {
if (devices == null) {
return;
}
for (int i = 0; i < devices.length; i++) {
if (devices[i] == null) {
continue;
}
Object actual = extractor.extractValue(devices[i]);
if (actual == null && expect== null) {
continue;
} else if (actual == null) {
devices[i] = null;
continue;
}
if (!Objects.equals(actual, expect)) {
devices[i] = null;
}
}
}
用法:
filterByType(devices, Device::getType, "Hello");
注意:由于没有泛型的要求,我使用了
Object
-因为唯一的调用方法是equals
,实际上这没什么大不了的。但是,为了获得更多的类型安全性,您可以引入泛型(并取消使用
DeviceValueExtractor
:public static <T> void filterByType(Device[] devices, Function<Device, T> extractor, T expect) {
if (devices == null) {
return;
}
for (int i = 0; i < devices.length; i++) {
if (devices[i] == null) {
continue;
}
Object actual = extractor.apply(devices[i]);
if (actual == null && expect== null) {
continue;
} else if (actual == null) {
devices[i] = null;
continue;
}
if (!Objects.equals(actual, expect)) {
devices[i] = null;
}
}
}
关于java - 违反Java中的DRY原则,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52747597/