Замена нулевых проверок с помощью ploymorphism - PullRequest
0 голосов
/ 16 января 2019

Недавно я читал книгу «Чистый код» Роберта Мартина, и в главе 7 был раздел, где он сказал, что вы должны попытаться заменить нулевые проверки, используя специальный шаблон разработки случая. Я подумал, что это отличная идея, но потом подумал о следующем примере.

foreach(thing in someCollection) {
    value = getValue();
    if(value == null) {
        break;
    }
    value.doSomething();
}

Вы можете сделать так, чтобы объект, возвращаемый getValue, был полиморфным, создать интерфейс с принудительным применением метода doSomething() и реализовать его для объекта, который вы хотите вернуть, и класс «mock» для специального случая ( если значение равно нулю). Это исключило бы необходимость в выражении gaurd, поскольку на самом деле не имеет значения, вызывается ли doSomething() для нашего «фиктивного» объекта, поскольку это фактический объект, имеющий метод doSomething():

 function doSomething(){
    return;
 } 

Единственная проблема в том, что цикл не прерывается. Насколько я могу судить, нет способа вырваться из цикла с использованием полиморфного класса, если возвращается «фиктивный» объект, если только у вас нет проверки на фиктивный объект, но тогда это побеждает точку.

У меня вопрос: есть ли чистый способ иметь дело с нулями, которые не влекут за собой эти вычислительные потери? Или я что-то неправильно понимаю о том, что сказано в главе 7 о проверках на ноль?

Ответы [ 2 ]

0 голосов
/ 16 января 2019

Шаблон специального случая или шаблон нулевого объекта используется для единообразного рассмотрения всех случаев. Это освобождает клиентский код от нескольких путей выполнения.

В приведенном вами примере особый случай должен трактоваться по-разному, потому что итерация должна быть остановлена ​​при обнаружении определенного значения (null в этом случае). Вы не можете применить решение для проблемы X для решения проблемы Y, особенно когда обе проблемы полностью противоположны.

0 голосов
/ 16 января 2019

Предположительно, break предназначен для предотвращения NullPointerException, поскольку достигнут конец сбора.Если целью является скорее фильтрация коллекции, то более подходящая конструкция (такая как Predicate) будет оправданной (и более читаемой).

На высоком уровне вы 'Мы заметили, что добавление небольшой ОО-конструкции в пакет процедурного кода может потребовать переосмысления предыдущей конструкции.Это часто правда.Если null используется в качестве точки останова в середине коллекции, перед реализацией шаблона нулевого объекта следует рассмотреть более серьезную проблему проектирования.

Хотя это все еще может быть хорошим сценарием для нулевого объекта-объектный шаблон (после рефакторинга цикла) шаблон не применим к каждому сценарию, в котором используется null.К сожалению, не все так просто.Optional - еще одно популярное решение, и есть еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...