Язык программирования C++ для профессионалов



     шаблон сайта скачать. |       

Абстрактные типы - часть 3


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

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

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

Почему мы не стали определять классы slist и vector как прямые производные от класса set, обойдясь тем самым без классов slist_set и vector_set? Другими словами зачем нужны конкретные типы, когда уже определены абстрактные типы? Можно предложить три ответа:

  1. Эффективность: такие типы, как vector или slist надо создавать без накладных расходов, вызванных отдалением реализаций от интерфейсов (разделения интерфейса и реализации требует концепция абстрактного типа).
  2. Множественный интерфейс: часто разные понятия лучше всего реализовать как производные от одного класса.
  3. Повторное использование: нужен механизм, который позволит приспособить для нашей библиотеки типы, разработанные "где-то в другом месте".




Содержание  Назад  Вперед