Java: использование instanceof для предоставления различных методов объекта - PullRequest
1 голос
/ 10 февраля 2012

Я прочитал эту статью http://www.javapractices.com/topic/TopicAction.do?Id=31,, в которой говорится, что использование instanceof для проверки того, что мой объект заранее, является плохой практикой.

Но я не знаю, как это сделать иначе в этомcase: у меня есть API, который возвращает список элементов.Этот список элементов возвращает как пользователей, так и администраторов

Если я разыграю элемент, подобный элементу (пользователю), я получу исключение ClassCastException, как только оно достигнет администратора

for(Item item : items){                     
                if (item instanceof User){
                    ((User)item).getName());
                    ((User)item).getEmail());
                }
                else if (item instanceof Admin){
                    ((Admin)item).getName());
                    ((Admin)item).getEmailList().getPrimary());
                }                           
            }

.это API, который я не могу изменить Item, Item не имеет методов для дочерних элементов, а метод извлечения электронной почты отличается.У меня есть другой выбор?

Ответы [ 3 ]

5 голосов
/ 10 февраля 2012

Определите интерфейс со всеми распространенными методами, пусть классы User и Admin реализуют его и используют только этот интерфейс для доступа к вашим объектам в этих случаях.

РЕДАКТИРОВАТЬ (потому что вы не можете изменить API)

Альтернативные варианты:

  1. Придерживайтесь вашего текущего решения. Это, кажется, лучшая сделка.

  2. Определите интерфейс, создайте два класса-обертки, которые реализуют этот интерфейс, и оберните исходные объекты. С точки зрения ООП это более чисто, но я думаю, что это немного завышено в вашем случае, но это действительно зависит.

  3. Теоретически (!): Вы также можете использовать отражение, но не делайте этого - это сделает код еще хуже - особенно если не известны только два различных времени компиляции Подтипы предметов

2 голосов
/ 10 февраля 2012

В идеале вы должны изменить интерфейс на Item, чтобы он отображал методы таким образом, чтобы не имело значения, имеете ли вы дело с пользователем или администратором в своем коде - чтобы Item определял как getName (), так и getEmail ().и пользователь и администратор реализуют эти методы соответствующим образом.

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

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

0 голосов
/ 10 февраля 2012

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

Во-вторых, плохо иметь коллекцию с элементами разных типов. В вашем случае пользователь и админ.

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

...