В одном из моих проектов у меня есть два «объекта передачи данных» RecordType1 и RecordType2, которые наследуются от абстрактного класса RecordType.Это использование оператора «instanceof» считается плохим дизайном?
Я хочу, чтобы оба объекта RecordType обрабатывались одним и тем же классом RecordProcessor в рамках метода «process». Моя первая мысль была создать универсальный метод обработки, что делегаты на двух конкретных методов процесса следующим образом:
public RecordType process(RecordType record){
if (record instanceof RecordType1)
return process((RecordType1) record);
else if (record instanceof RecordType2)
return process((RecordType2) record);
throw new IllegalArgumentException(record);
}
public RecordType1 process(RecordType1 record){
// Specific processing for Record Type 1
}
public RecordType2 process(RecordType2 record){
// Specific processing for Record Type 2
}
Я прочитал, что Скотт Мейерс пишет следующее в Эффективное использование C++:
«В любое время вы найдите код написания формы «если объект имеет тип T1, затем сделайте что-нибудь, но если он имеет тип T2, тогда сделайте что-нибудь еще,« похлопайте себя ».
Если он прав, я должен похлопать себя. Я действительно не вижу, как это плохой дизайн (если, конечно, кто-то не подклассирует RecordType и не добавляет в RecordType3, не добавляя еще одну строку к общему методу «Process», который обрабатывает его, создавая таким образом NPE), и альтернативы, которые я могу думать связанные с тем, что накладывают основную нагрузку на конкретную логику обработки внутри самих классов RecordType, что на самом деле не имеет для меня большого смысла, поскольку теоретически может быть много разных типов обработки, которые я бы хотел выполнить на этих записях.
Может кто-нибудь объяснить, почему это может считаться плохим дизайном и предоставить какую-то альтернативу, которая все еще несет ответственность за обработку этих записей классу «Обработка»?
UPDATE:
- Изменено
return null
кthrow new IllegalArgumentException(record);
- Просто чтобы прояснить, есть три причины простой RecordType.process() метод не будет достаточно: во-первых, обработка действительно слишком далеко из RecordType, чтобы заслужить свой собственный метод в подклассах RecordType. Кроме того, существует целый ряд различных типов обработки, которые теоретически могут выполняться разными процессорами. Наконец, RecordType разработан как простой класс DTO с минимальным изменением состояния, определяемым внутри.
Обычно это плохой знак. Но нам нужно понять, что вы пытаетесь сделать - и это не ясно из вопроса. Как правило, кажется, что все ваши типы имеют одинаковую функцию, поэтому вы можете просто использовать интерфейсы. – Yossale
В чем разница между RecordType1 и 2? Можете ли вы заставить их придерживаться одного и того же интерфейса? – kba
Вы вообще не хотите этого делать, но если вы только когда-нибудь увидите эту логику, высказанную один раз, возможно, вы живете с ней. Если вы начнете видеть ту же логику 'if (instanceof X), выраженную в нескольких местах, тогда вам действительно нужно ударить себя. –