Не используйте типовые тесты, объявите doTheTask?
Я прохожу через Java для всех от Cay Horstmann.
Я немного смущен, когда он говорит:
Не используйте типовые тесты
Это об использовании instanceof
оператор для тестов конкретного типа, чтобы реализовать поведение, которое варьируется в зависимости от каждого класса (взято прямо из книги):
if (q instanceof ChoiceQuestions) //Don't do this
{
//Do the task the ChoiceQuestion way
}
else if (q instanceof Question)
{
//Do the task Question way
}
Видимо, это плохой способ сделать это, как будто у вас есть новый класс, как NumericQuestion
добавил, что вам нужно пересмотреть все части вашей программы, которые делают типовой тест, добавив еще один случай.
Лучше добавить класс NumericQuestion
к программе. Ничего не нужно менять, так как мы используем полиморфизм, а не тесты типов. Если вы когда-нибудь пытаетесь использовать тесты типа в иерархии классов, пересмотрите и используйте вместо этого полиморфизм. Объявить метод doTheTask
в суперклассе, переопределите его в подклассах и вызовите q.doTheTask()
Что я не понимаю, так это последний абзац, приведенный выше. Может кто-нибудь подсунуть мне пример того, что это значит, пожалуйста? (Я отчасти визуальный ученик). Как мы можем сделать это без использования тестов?
3 ответа
Дело в том, что вместо этого:
if (q instanceof ChoiceQuestions) //Don't do this
{
//Do the task the ChoiceQuestion way
}
else if (q instanceof Question)
{
//Do the task Question way
}
Вы должны сделать это:
q.doTheTask();
где Question
класс содержит:
public void doTheTask(String someParameter){
//Do the task Question way
}
и ChoiceQuestion
класс содержит
public void doTheTask(String someParameter){
//Do the task the ChoiceQuestion way
}
Затем, когда вы получаете новый класс DrawQuestion
будет содержать
public void doTheTask(String someParameter){
//Do the task the DrawQuestionway
}
но ни один из кода, который вызывает doTheTask()
придется менять! Там нет риска, как это с if (q instanceof ChoiceQuestions)
шаблон, забыв добавить новую логику. И (это на самом деле самая важная часть в долгосрочной перспективе) вся логика, которая касается конкретного вида Question
сосредоточено в одном классе, а не распределено по всем частям приложения.
Вы должны понимать, что класс отвечает за свое поведение, а не за вызывающую часть из exmaple. Я узнал это как принцип "стол должен нарисовать сам":
Визуализируйте мебель. У вас есть класс живописца, который рисует мебель, но вы должны "научиться" ему, как красить мебель нового типа каждый раз, когда вы ее объявляете. Так
Художник:
if (q instanceof Table) //Don't do this
{
//paint table
}
else if (q instanceof Closet)
{
//paint closet
}
То, что вы делаете, это то, что вы заставляете всю мебель расширять класс мебели, который знает метод paintThySelf()
, Так что теперь художник просто делает
q.paintThySelf()
И если вы добавите класс кафедры, вам придется добавить paintThySelf()
метод, и вы можете нарисовать его.
В качестве принципа проектирования предпочтение отдается созданию подкласса с другим (переопределенным) поведением по сравнению с использованием instanceof
контролировать поведение.