Проверка типов когда-нибудь ОК?

Считается ли проверка типов плохой практикой, даже если вы проверяете интерфейс? Я понимаю, что вы всегда должны программировать интерфейс, а не реализацию - это то, что это значит?

Например, в PHP это нормально?

if ($class instanceof AnInterface) {
   // Do some code
}

Или есть лучший способ изменить поведение кода на основе типа класса?

Редактировать: Для ясности я говорю о проверке того, является ли класс орудия интерфейсом, а не просто экземпляром определенного класса.

В PHP
В PHP
В большой кодовой базе с множеством различных компонентов классы, функции и константы могут иметь одинаковые имена. Это может привести к путанице и...
Принцип подстановки Лискова
Принцип подстановки Лискова
Принцип подстановки Лискова (LSP) - это принцип объектно-ориентированного программирования, который гласит, что объекты суперкласса должны иметь...
1
0
511
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Если вы можете избежать проверки типов, вам следует; однако один сценарий, в котором я нашел это удобным, заключался в том, что у нас была веб-служба, принимающая сообщение, но содержимое сообщения могло измениться. Нам пришлось сохранить сообщение обратно в базу данных, чтобы получить правильный компонент, чтобы разбить сообщение на соответствующие таблицы, мы в некотором смысле использовали проверку типов.

То, что я считаю более распространенным и гибким, чем if ($ class instanceof SomeOtherType), - это, например, определение стратегии IProcessing, а затем использование factory на основе типа $ class для создания правильного класса.

Итак, в C# примерно это:

void Process(Message msg)
{
    IProcessor processor=ProcessignFactory.GetProcessor(msg.GetType()); 
    processor.Process(msg); 
}

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

Ответ принят как подходящий

Пока вы следуете LSP, я не вижу проблемы. Ваш код должен работать с реализацией интерфейса любой. Не проблема, что определенные реализации заставляют вас следовать различным путям кода, если вы можете правильно работать с реализацией интерфейса любой.

Если ваш код не работает со всеми реализациями интерфейса, вам не следует использовать интерфейс в первую очередь.

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

Brian Rasmussen 15.01.2009 22:05

Конечно, пока подкласс реализует интерфейс, никаких изменений вносить не нужно?

Tim Wardle 15.01.2009 22:10

В моей практике любая проверка типа (а также приведение типов) всегда указывала на то, что что-то не так с кодом или языком.

Поэтому я стараюсь по возможности избегать этого.

Как эффективно определять количество элементов в бесчисленной коллекции без приведения типов?

supercat 16.04.2013 19:45

Проверка типов во время выполнения часто необходима в ситуациях, когда интерфейс предоставляет все методы, необходимые для того, чтобы что-то делать, но не предоставляет достаточно, чтобы делать это хорошо. Ярким примером такой ситуации является определение количества элементов в перечислимой последовательности. Такое определение можно сделать путем перечисления в последовательности, но многие перечислимые объекты «знают», сколько элементов они содержат. Если объект знает, сколько элементов он содержит, вероятно, будет более эффективным запросить его, чем перечислять через коллекцию и подсчитывать элементы по отдельности.

Возможно, IEnumerable должен был предоставить некоторые методы, чтобы спросить, что ему известно о количестве элементов, которые он содержит [признавая возможность того, что объект может знать, что это число неограниченно или что оно не превышает 4591 (но может быть намного меньше), и т. д.], но это не так. Идеальным было бы создание новой версии интерфейса IEnumerable, которая включала бы реализации по умолчанию для любых «новых» методов, которые он добавляет, и если бы такой интерфейс можно было считать реализованным любыми реализациями текущей версии. К сожалению, поскольку такой функции не существует, единственный способ получить счетчик перечисляемой коллекции без ее перечисления - это проверить, реализует ли она какие-либо известные интерфейсы коллекции, которые включают член Count.

Это просто проблема с методами расширения C#, поскольку они разрешаются статически и не являются полиморфными. Если бы C# поддерживал черты, классы могли бы специализироваться на реализации Count, если бы они могли обеспечить более эффективную реализацию.

Lee 16.04.2013 20:30

@Lee: Правильный подход, IMHO, состоял бы в том, чтобы иметь код в загрузчике классов .NET, который мог бы обрабатывать методы интерфейса, для которых не существует реализации, указав vtable на статическую реализацию, связанную с интерфейсом [одна версия для структур и один для классов], сигнатура которого включала в качестве первого параметра ссылку или byref на тип реализации. Это добавило бы немного времени к процессу загрузки класса, но позволило бы интерфейсам, таким как IList<T>, включать методы, которые были бы полезны с некоторыми, но не всеми реализациями, без принуждения ...

supercat 16.04.2013 21:06

... все реализации IList<T> включают стандартные заглушки для неиспользуемых методов.

supercat 16.04.2013 21:06

Другие вопросы по теме