Главная » Разработка для Android » Использование полиморфизма и композиции – Android

0

 

При разработке для Android, как и в других объектно-ориентированных средах, применяются полиморфизм и композиция – превосходные инструменты, дополняющие среду разработки. В предыдущем примере были продемонстрированы как полиморфизм, так и композиция. Давайте ненадолго остановимся, заострим внимание на этих концепциях и заново рассмотрим их ценность – теперь в контексте целей разработки.

Анонимный экземпляр TextWatcher, передаваемый addTextChangedListener в качестве объекта обратного вызова, использует композицию для реализации такого поведения. Экземпляр сам по себе не реализует никаких поведений. Вместо этого он делегирует задачу реализации методу handleTextChange, относящемуся к модели MyModel, предпочитая реализацию отношения has-a реализации самого требуемого поведения. Таким образом, функции ясно и четко разделяются. Если MyModel потребуется расширить еще сильнее, например, для применения текста, получаемого из иного источника, то новый источник также будет использовать handleTextChange. Не придется отслеживать код сразу в нескольких отдельных анонимных классах.

На данном примере также демонстрируется использование полиморфизма. Экземпляр, передаваемый методу addTextChangedListener, обладает сильной статической типизацией. Это анонимный подтип TextWatcher. Данная конкретная реализация – в нашем случае делегирование задачи handleTextChange в MyModel -практически наверняка не будет походить ни на одну другую реализацию данного интерфейса. Тем не менее, поскольку это реализация интерфейса TextWatcher, он будет иметь статическую типизацию, независимо от того, как именно он выполняет свою задачу. Компилятор может гарантировать, что методу addTextChangedListener в EditText передаются только такие объекты, которые как минимум предназначены для выполнения поставленной задачи. Реализация не застрахована от ошибок, но как минимум addTextChangedListener никогда не получит объект, предназначенный для обработки сетевых событий. В этом и есть суть полиморфизма.

В данном контексте следует упомянуть об одном антипаттерне, так как он встречается очень часто. Многие разработчики считают анонимные классы слишком пространным и неуклюжим способом передачи указателя к функции. Чтобы обойтись без анонимных классов, такие разработчики вообще опускают объект-мес-сенджер вот так:

В некоторых ситуациях такой подход оправдан. Если клиент обратного вызова (в данном случае модель MyModel) мал, прост и используется всего в двух контекстах, код получится ясным и уместным.

С другой стороны (об этом подсказывает название MyModelкласс будет широко использоваться при довольно разных обстоятельствах, а в этом случае попытка обойтись без классов-мессенджеров нарушает инкапсуляцию и ограничивает возможности расширения кода. Очевидно, если такую реализацию придется расширить для обработки ввода, получаемого из второго TextBox, и задействовать при этом иное поведение, код получится путаным.

Но практически так же порочна и ситуация, иногда называемая загрязнением интерфейса (interface pollution). Она возникает, когда описанная выше идея выражается чрезмерно сильно. Получается нечто подобное:

Подобный код в определенном смысле кажется заманчиво-элегантным, такой код встречается довольно часто. Но, к сожалению, теперь MyModel слишком тесно связана со всеми обрабатываемыми ею событиями.

В большинстве случаев не удается сформулировать «железных» правил по борьбе с загрязнением интерфейса. Как уже было отмечено, существует масса действующего кода, который выглядит именно так. Но все же чем меньше интерфейс, тем меньше в нем возникает сбоев и тем проще его изменять. Когда интерфейс объекта расширяется настолько, что уже явно кажется вам некрасивым, попробуйте разбить его на мелкие фрагменты, которыми будет легко управлять. Для этого применяется композиция.

Источник: Android. Программирование на Java для нового поколения мобильных устройств

По теме:

  • Комментарии