Нарушение принципа СУХОЙ в Java - PullRequest
0 голосов
/ 10 октября 2018

У меня есть три метода, которые фильтруют массив устройств по полю.

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;
        }
    }
}

Другие методы аналогичны.Единственная разница заключается в вызове другого получателя поля, к которому применяется фильтрация.Например, есть звонок на getModel() вместо getType().Это нарушает принцип СУХОГО и как я могу изменить его так, чтобы он не (без генериков)?

PS Это домашняя работа, и, к сожалению, мы еще не используем дженерики.Я также не могу изменить подпись методов.У меня есть подсказка, что я могу создать внутренний класс с помощью одного метода, который будет вызывать необходимый метод get и возвращать значение.Итак, мне нужно поместить все свои проверки в этот метод, но я не совсем понимаю, как это сделать с моей логикой (особенно с «продолжить»).

Ответы [ 3 ]

0 голосов
/ 10 октября 2018

Вы можете создать 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;
        }
    }
}
0 голосов
/ 10 октября 2018

Это более простая версия.Вы можете использовать необработанные типы, но это будет более подвержено ошибкам.

public static <T> void filtrateByType(T[] objects, Function<T, String> function, String type) {
    if (objects == null || type == null)
        return;
    for (int i = 0; i < objects.length; i++) {
        if (objects[i] == null) continue;
        String match = function.apply(objects[i]);
        if (match == null || !match.equals(type)) 
            objects[i] = null;
    }
}

Однако я подозреваю, что вы действительно хотите использовать Stream API

Device[] filtered = Stream.of(devices)
                          .filter(d -> Objects.equals(d.getType(), type))
                          .toArray(Device[]::new);
0 голосов
/ 10 октября 2018

Возможно, здесь поможет магия Java 8:

public void filtrateByType(Device[] devices, String type) {
    filtrateBy(devices, Device::getType, type);
}

public void filtrateBy(Device[] devices, Function<? super Device, String> attributeGetter, String attribute) {
    if (devices == null) {
        return;
    }
    for (int i = 0; i < devices.length; i++) {

        if (devices[i] == null) {
            continue;
        }

        if (attributeGetter.apply(devices[i]) == null && attribute == null) {
            continue;
        } else if (attributeGetter.apply(devices[i]) == null) {
            devices[i] = null;
            continue;
        }
        if (!attributeGetter.apply(devices[i]).equals(attribute)) {
            devices[i] = null;
        }
    }
}
...