Это плохое решение ввести метод только для исключения? - PullRequest
2 голосов
/ 17 декабря 2011

Я сейчас думаю о концепции, которая должна относиться к незаконным состояниям в моей Java-программе. Я ввел класс, который выполняет этапы обработки изображений.

public class ImageProcessor{
    public Image processImage(Image img){
       //do some processing steps
    }
}

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

public class ImageChecker{
     public void checkImage(Image img) throws ImageNotProcessableException{
         //for example, if the image has a width of 0 the full process
         //should be broken, throw an exception
         if (img.width=0) throw new ImageNotProcessableException("width is 0");

         //other conditions throwing also exceptions

         // the image is fine, do nothing
     }
}

Два класса должны использоваться в классе координатора.

 public class Coordinator{
    public void coordinate(Image img) throws ImageNotProcessableException{
       //initialize both

       imageChecker.checkImage(img); //if no exception is throw the process can run
       imageprocessor.processImage(img);
    }
 }

Вопрос теперь в том, является ли этот способ обработки Exception (определения отдельного метода для них) плохим стилем кодирования? Идея этого проекта состояла в том, чтобы предотвратить загрязняющий код обработки с обработкой исключений. Я хочу, чтобы координатор выбросил исключения, и я подумал, что это может быть разумным способом. Как вы думаете, это хороший способ или это антипаттерн. Спасибо!

Ответы [ 3 ]

4 голосов
/ 17 декабря 2011

Сам метод валидации - очень хорошая идея.Вы вводите очень хорошее разделение задач - проверка предварительных условий и проверка в одном месте и фактическая обработка в другом.

Однако использование некорректно.ImageProcessor должен охотно позвонить ImageChecker.checkImage().В противном случае клиент вашей библиотеки может забыть вызвать его и передать недопустимое изображение.

Также * @ Damien_The_Unbeliever * поднимает очень хороший вопрос о структуре кода.Я бы хотел создать интерфейс ImageProcessor с двумя реализациями: одна, которая выполняет фактическую обработку, и декоратор реализация (ImageChecker), которая выполняет проверку и передает проверенный объект вtarget ImageProcessor.

Таким образом, вы можете использовать безопасную или быструю (если проверка будет дорогостоящей) реализацию.Также в будущем вы можете ввести в цепочку 1019 * другие элементы, такие как кэширование или профилирование.

1 голос
/ 19 декабря 2011

Я вижу здесь 3 вопроса, и их полезно разделить.

  1. Должен ли вызывающий объект видеть класс с именем «ImageProcessor» или класс с именем «Координатор»?

  2. Хорошо ли проводить проверку входных данных отдельным методом от основной обработки?

  3. Должен ли этот код использовать проверенные или непроверенные исключения?

Мои ответы будут такими:

  1. Используйте более красивое имя для представляемых вами классов или интерфейсов.Итак, здесь «ImageProcessor» гораздо приятнее, чем «Координатор».(«Координатор» звучит как деталь реализации, которую вы не хотите раскрывать.)

  2. Это решение о реализации.Можно разделить некоторую логику проверки на отдельный метод, если он делает вещи чище.Но вы должны быть осторожны, чтобы не оказаться в ловушке, думая, что можно заранее предвидеть все, что может пойти не так на более поздних этапах обработки.Метод, который выполняет фактическую обработку, все еще должен быть свободным для создания исключений, чтобы он мог описывать сбои как можно точнее, независимо от того, что было решено при первоначальной быстрой проверке.Кроме того, вы хотите избежать написания кода проверки в двух местах, так как это является ненужным дублированием кода.Итак, я немного скептически отношусь к такому разделению, но мне нужно увидеть код.Скорее всего, лучше разделить саму фактическую обработку изображений на различные подзадачи и выполнить проверку в том месте, где вам это нужно.

  3. Это проверенные Java-исключениядебаты, которые не уйдут в нашей жизни, и их невозможно суммировать здесь.Но я думаю, что консенсус довольно сильно сместился в пользу использования исключения во время выполнения, а не проверенного исключения.Конечно, устаревшие API все еще используют проверенные исключения.Но для большинства нового кода лучше использовать исключения времени выполнения, а не проверенные исключения, поскольку это позволяет сделать код более надежным.(Проверенные исключения имеют раздражающее свойство часто оборачиваться, перематываться, проглатываться или иным образом искажаться, прежде чем они смогут добраться до обработчика исключений, и они наносят много сопутствующего ущерба на этом пути, заставляя каждый пункт throws становиться длиннее.)

1 голос
/ 17 декабря 2011

Это не лишено смысла.Хотя, если checkImage существует с единственной целью проверить, нормально ли обрабатывать изображение и не имеет другого возвращаемого типа, было бы разумно, чтобы оно возвращало код состояния / объект, а не выдавало исключение и возвращало void, например,

ImageStatus status = checkImage(image);
if (status.isOk()) { 
  processImage(image);
}

Это было бы аналогично проверке деления на ноль:

if (y != 0) {
  z = x / y;
}

Проверенные исключения, как правило, лучше подходят для ситуаций, когда вы не можете априори подтвердить, что-то получится или не получитсяпока не попробуешь, например, IOException.

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