Наверное самый распространенный случай использования интерфейсов следующий.

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

Рассмотрим пример.

Пусть существует графический редактор с различными панелями и модулями. Необходимо сохранять расположение и настройки этих панелей для следующего сеанса работы с пользователем. Система каждый раз при закрытии, опрашивает все панели на предмет сохраняемых данных, а при следующей загрузке раздает данные обратно. В этом случае можно реализовать интерфейс IRestoreable с методами getRestoreData и setRestoreData, которые служат для получения и установки данных в панель или модуль.

Пример интерфейса.

  1.  
  2. /**
  3. * Интерфейс для элементов с восстанавливаемым состоянием.
  4. * @author J.Nikolaeva
  5. * @version 20.12.2006
  6. */
  7. interface IRestoreable {
  8.         /**
  9.          * Возвращаем данные о состоянии.     
  10.          * @return данные о состоянии
  11.          */
  12.         public function getRestoreData():PanelStateData;
  13.         /**
  14.          * Установка данных о состоянии.
  15.          * @param data - данные о состоянии
  16.          * @return ничего
  17.          */
  18.         public function setRestoreData(data:PanelStateData):Void;
  19. }
  20.  

Теперь если реализовать данный интерфейс для панелей и модулей редактора, то можно будет общаться с ними единообразно. Например, пусть классы SizePanel и ColorMixerPanel реализуют данный интерфейс. Из следующего примера понятно, в каком русле можно организовать общение главного приложения с ними.

  1.  
  2. /**
  3. * Приложение графический редактор.
  4. * @author J.Nikolaeva
  5. * @version 20.12.2006
  6. */
  7. class Application {
  8.         private var sizePanel:IRestoreable;
  9.         private var colorMixer:IRestoreable;
  10.        
  11.        
  12.         /**
  13.         * Конструктор.
  14.         */
  15.         public function Application() {
  16.                 sizePanel = new SizePanel();
  17.                 colorMixer = new ColorMixerPanel();
  18.                 sizePanel.setRestoreData(new PanelStateData());
  19.                 colorMixer.setRestoreData(new PanelStateData());
  20.         }       
  21. }
  22.  

Какие здесь плюсы?

  1. Можем общаться со всеми модулями одинаково.
  2. Получаем ошибки на этапе компиляции, если обращаемся ‘неправильно’ или ‘не к тому’ методу.
  3. Не ограничиваем модули одним предком.
  4. Разрешение ситуации, когда модули и панели уже написаны, а функционал сохранения их состояния необходимо добавить только сейчас.

Хочется упомянуть один момент. Понятное дело, что модули и панели редактора могут иметь и другой общий функционал - изменение размера, перемещение, привязка к другой панели. Тогда возможно появление желания сделать общий интерфейс для таких элементов, например, IEditorPanel, в котором определить все необходимые уважающей себя панели методы.

Стоит быть осторожными, так как это может в дальнейшем связать вам руки. Например, только нектором модулям необходимы методы getRestoreData и setRestoreData, но они включены в этот общий интерфейс, по которому происходит все общение системы с панелями. Тогда вы будете вынуждены определить эти методы во всех панелях, хоть и пустыми, что может привести к недоразумениям. А может случится так, что прийдется изменить сигнатуру какого-нибудь метода в интерфейсе, тогда вы будете вынуждены вносить изменения во все элементы, даже в те, где эти методы объявлены пустыми. Более гибким решением может быть использование нескольких интерфейсов, таких как IResizeable, IRelocatable и т. д.

Трекбек адрес этой записи

URL трекбека (щелкните правой кнопкой мыши и скопируйте ссылку)

3 комментариев

Комментарий от: Юрий Яровой [Посетитель] Email · http://www.yarovoy.com
В блоге не работает пред.просмотр комментария. Только что потерял из-за этого коммент. Обидно. Заново писать - лень. =)
2006-12-21 @ 11:48
Комментарий от: Nirth [Посетитель] Email · http://orangeflash.eu
только не colorMoxer а Mixer =)
2006-12-25 @ 17:08
ответ для Nirth

Спасибо, поправлю. :)
2007-01-11 @ 14:14

Оставить комментарий


Ваш email адрес. (Не будет показан на сайте.)

Ваш URL будет показан.
:!: :?: :idea: :) :D :p B) ;) :> :roll: :oops: :| :-/ :( :'( |-| :>> :yes: ;D :P :)) 88| :. :no: XX( :lalala: :crazy: >:XX
(Заменить прерывания строк на <br />)
(Имя, email и сайт)
(Разрешить пользователям посылать вам сообщения (ваш email не отображается).)
3 + 2 + 7 - 1?
antispam test

Вы можете использовать OpenID чтобы предоставить ваше имя, email и url.