Показаны сообщения с ярлыком ООП. Показать все сообщения
Показаны сообщения с ярлыком ООП. Показать все сообщения

суббота, 11 февраля 2012 г.

Об иерархиях наследования

Очередная интересная мысль от Бертрана Мейера, на этот раз касается она проектирования иерархий объектов:

Произвольно или нет, но многие учебные презентации создают впечатление, что структуру наследования следует проектировать от наиболее общего (верхней ее части) к более специфическим частям (листьям). В частности, это происходит потому, что лучший способ описать существующую структуру – это идти от общего к частному, от фигур к замкнутым фигурам, затем к многоугольникам, прямоугольникам, квадратам. Но лучший способ описания структуры вовсе не означает, что он является и лучшим способом ее создания.

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

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

воскресенье, 29 января 2012 г.

Сказка о повторном использовании

Очередная цитата из книги Бертрана Мейера “Объектно-ориентированное конструирование программных систем”.

Эта сказка опубликована в разделе “Сказка о поиске классов”, но мое название, мне кажется более уместным (после прочтения будет ясно, почему).

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

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

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

Наконец, в один из темных зимних дней, когда снег покрыл все окружающие горные вершины, он вошел в комнату Мастера. С бьющимся сердцем, пересохшим от волнения голосом он задал свой сакраментальный вопрос: "Мастер, как мне найти классы?"

Мудрец склонил свою голову и ответил медленно и спокойно: "Возвращайся назад, откуда пришел. Классы уже найдены".

Оглушенный, он и не заметил, как слуги Мастера выводили его прочь. "Мастер", - теперь он почти кричал, - "пожалуйста, еще только один вопрос. Как называется эта история?" Старый Учитель покачал головой: "Разве ты еще не понял? Это сказка о повторном использовании".

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

Мейер в своей книге повторяет, наверное, десятки раз о том, что в современном мире проектирование должно сводиться не к “выявления” новых абстракций, а к выбору готовых классов, которые можно было бы использовать повторно.

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

суббота, 10 сентября 2011 г.

Еще раз о повторном использовании

Сегодня открыл книгу “банды четырех”, чтобы уточнить определение одного из паттернов проектирования и в первой же главе увидел выделенную когда-то цитату:

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

Эрик Липперт, один из разработчиков компилятора C# очень часто говорит о проблеме “преждевременного обобщения” (premature generialization), с которой я, например, сталкиваюсь постоянно.

Многие разработчики разрабатывают повторноиспользуемые компоненты (или выделяют их из своего приложения) принимая во внимание лишь один кейс использования. Они пытаются предсказать будущее, рассматривая какие-то гипотетические кейсы использования или делают “задел на будущее”, который никогда не понадобится. В итоге “библиотечный код” получается излишне сложным и совсем не таким “повторноиспользуемым”, как о нем думал его разработчик.

вторник, 4 мая 2010 г.

Об изменениях в ПО

Изменения в ПО неизбежны. Задача в том, чтобы уметь управлять ими.

Бертран Мейер “Объектно-ориентированное конструирование программных систем”.

понедельник, 12 апреля 2010 г.

Анализ задачи

Анализ должен объяснить, что делает система, а не то, как она это делает.

Гради Буч. Объектно-ориентированный анализ и проектирование с примерами приложений

среда, 31 марта 2010 г.

Объектно-ориентированный анализ и проектирование. Часть 4

OOA and OOP

Возвращаемся к замечательной книге Гради Буча “Объектно-ориентированный анализ и проектирование с примерами приложений”.

Как отмечает Дейкстра, "Способ управления сложными системами был известен еще в древности - divide et impera (разделяй и властвуй)". При проектировании сложной программной системы необходимо разделять ее на все меньшие и меньшие подсистемы, каждую из которых можно совершенствовать независимо.
Глава 1.3 Роль декомпозиции

Объектная декомпозиция существенно снижает риск при создании сложной программной системы, так как она развивается из меньших систем, в которых мы уже уверены.
Глава 1.3 Роль декомпозиции

Объекты обладают целостностью, которая не должна - а, в действительности, не может - быть нарушена. Объект может только менять состояние, вести себя, управляться или становиться в определенное отношение к другим объектам. Иначе говоря, свойства, которые характеризуют объект и его поведение, остаются неизменными
Глава 2.1 OOP, OOD и OOA

Абстракция и икапсуляция дополняют друг друга: абстрагирование направлено на наблюдаемое поведение объекта, а инкапсуляция занимается внутренним устройством.
Глава 2.1 Инкапсуляция

Лисков прямо утверждает, что "абстракция будет работать только вместе с инкапсуляцией". Практически это означает наличие двух частей в классе: интерфейса и реализации. Интерфейс отражает внешнее поведение объекта, описывая абстракцию поведения всех объектов данного класса. Внутренняя реализация описывает представление этой абстракции и механизмы достижения желаемого поведения. Принцип разделения интерфейса и реализации соответствует сути вещей: в интерфейсной части собрано все, что касается взаимодействия данного объекта с любыми другими объектами; реализация скрывает от других объектов все детали, не имеющие отношения к процессу взаимодействия объектов.
Глава 2.1 Инкапсуляция

Разумная инкапсуляция локализует те особенности проекта, которые могут подвергнуться изменениям.
Глава 2.1 Инкапсуляция

Сокрытие информации - понятие относительное: то, что спрятано на одном уровне абстракции, обнаруживается на другом уровне.
Глава 2.1 Инкапсуляция

Деление программы на модули бессистемным образом иногда гораздо хуже, чем отсутствие модульности вообще.
Глава 2.1 Модульность

Следует стремиться построить модули так, чтобы объединить логически связанные абстракции и минимизировать взаимные связи между модулями.
Глава 2.1 Модульность

При коллективной разработке программ распределение работы осуществляется, как правило, по модульному принципу и правильное разделение проекта минимизирует связи между его участниками.
Глава 2.1 Модульность

Значительное упрощение в понимании сложных задач достигается за счет образования из абстракций иерархической структуры.
Глава 2.1 Иерархия

пятница, 5 марта 2010 г.

Алан Шаллоуей и Джеймс Р. Тротт. Шаблоны проектирования. Несколько слов о работе с заказчиком

Design Patterns Explained

Это последняя цитата из замечательной книги Алана Шаллоуейа и Джеймса Тротта “Шаблоны проектирования”, которую я хотел бы здесь опубликовать. Честно говоря сам я не ожидал, что в такой небольшой книге как эта окажется такое количество интересных цитат, но перечитывая свои записи даже спустя года два после прочтения книги я все еще нахожу их весьма интересными.

Последняя цитата (да, всего одна) касается очень популярной темы среди авторов книг (но о которой все еще не знают все разработчики) - теме общения с заказчиком. Об этом действительно говорится много (отличная подборка высказываний есть у Джоэла Спольски, см. “Секреты айсберга”), но я об этом впервые прочел именно в этой книге.

Обширный опыт общения с заказчиками позволил мне понять несколько важных моментов.
- Как правило, заказчики знают проблемную область очень хорошо (более того, они знают ее лучше, чем я когда-либо буду знать).
- Чаще всего заказчики не воспринимают предметную область на концептуальном уровне, как это принято у разработчиков. Напротив, они говорят о конкретных проявлениях тех или иных частных случаев.
- Заказчики часто используют определение "всегда", но на самом деле следовало бы говорить "обычно".
- Также часто они используют определение "никогда", подразумевая "редко".
- Заказчики часто утверждают, что рассказали обо всех возможных ситуациях, тогда как в действительности речь шла только о том, что случается обычно.
Подводя итог, можно сказать, что я полностью доверяю объяснениям заказчиков, когда они дают ответы на заданные мной конкретные вопросы, но с большим сомнением отношусь к их общим рассуждениям. Я всегда стараюсь вести диалог с заказчиком на максимально конкретном уровне. Даже те из заказчиков, которые полагают, что они способны осмыслить задачу на концептуальном уровне, в попытках оказать помощью разработчику часто переоценивают свои возможности.
Глава 20. Вариации в учебном примере - система международной электронной торговли

 

Все цитаты из книги книги Алана Шаллоуейа и Джеймса Тротта “Шаблоны проектирования”:

Часть 1

Часть 2

Часть 3

Несколько слов о работе с заказчиком

четверг, 4 марта 2010 г.

Алан Шаллоуей и Джеймс Р. Тротт. Шаблоны проектирования. Часть 3

Design Patterns Explained

Суждение о том, что некоторое здание является красивым, - это не просто вопрос вкуса. Красоту можно описать с помощью объективных критериев, которые могут быть измерены.
Кристофер Александер об объективных категориях качествах
Глава 5. Шаблоны проектирования пришли из области архитектуры и культурологии

Каждый шаблон описывает проблему, которая возникает в данной среде снова и снова, а затем предлагает принцип ее решения таким способом, который можно будет применять многократно, получая каждый раз результаты, не повторяющие друг друга.
Глава 5. Шаблоны проектирования пришли из области архитектуры и культурологии

Шаблоны проектирования предоставляют нам абстрактный высокоуровневый взгляд как на проблему, так и на весь процесс объектно-ориентированной разработки. Это помогает избежать излишней детализации на ранних стадиях проектирования.
Глава 5. Зачем нужно изучать шаблоны проектирования

Шаблоны позволяют нам видеть лес за деревьями, поскольку помогают поднять уровень мышления.
Глава 5. Зачем нужно изучать шаблоны проектирования

Наличие возможности реализовать что-либо вовсе не означает, что это обязательно должно быть выполнено.
Глава 13. Принцип проектирования от контекста

Все цитаты из книги книги Алана Шаллоуейа и Джеймса Тротта “Шаблоны проектирования”:

Часть 1

Часть 2

Часть 3

Несколько слов о работе с заказчиком

Алан Шаллоуей и Джеймс Р. Тротт. Шаблоны проектирования. Часть 2

Design Patterns Explained

Связность (cohesion) определяет, насколько тесно внутренние элементы подпрограммы взаимодействуют между собой. Связанность (coupling) характеризует, насколько тесно подпрограмма связана с другими подпрограммами. При этом целью разработчика является создание подпрограмм, обладающих внутренней целостностью (сильной связностью) и слабой, прямой, явной и гибкой зависимостью от других подпрограмм (слабая связанность).
Глава 1. Внесение изменений при использовании метода функциональной декомпозиции

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

При использовании метода функциональной декомпозиции постоянное изменение требований сводило все мои усилия по разработке и сопровождению программного обеспечения на нет. Главные проблемы были связаны с функциями. Внесение изменений в одну группу функций или данных неизбежно приводило к необходимости внесения изменений в другую группу функций или данных, что, в свою очередь, затрагивало следующую группу функций и т.д. Функциональная декомпозиция приложения приводит к каскадным изменениям, подобным снежному кому, скатывающемуся с высокой горы, избежать которых достаточно сложно.
Глава 1. Внесение изменений при использовании метода функциональной декомпозиции

Инкапсуляцию чаще всего определяют как сокрытие данных. Объекты обычно не разрешают доступ извне к своим внутренним данным-членам (т.е. для этих элементов указывается уровень доступа защищенный или закрытый). Однако инкапсуляция представляет собой нечто большее, чем просто сокрытие данных. В общем случае понятие инкапсуляции охватывает любой тип сокрытия.
Глава 1. Объектно-ориентированная парадигма

Руководствуйтесь своей интуицией
Интуитивная оценка - это на удивление эффективный индикатор качества создаваемого проекта. Я полагаю, что будущих разработчиков программного обеспечения следует приучать полагаться на свою интуицию.
Под интуицией я здесь понимаю то особой ощущение, которое возникает у вас при взгляде на что-то такое, что вам не нравится. Я понимаю, что подобное определение звучит крайне ненаучно (и это действительно так), однако мой личный опыт убедительно доказывает, что если проектное решение мне интуитивно не нравится, то где-то рядом обязательно имеется лучшее. Безусловно, иногда можно предложить сразу несколько возможных направлений совершенствования, и выбор лучшего из них бывает не вполне очевиден.
Глава 4. Решение с обработкой особых случаев

Все цитаты из книги книги Алана Шаллоуейа и Джеймса Тротта “Шаблоны проектирования”:

Часть 1

Часть 2

Часть 3

Несколько слов о работе с заказчиком

вторник, 26 января 2010 г.

Объектно-ориентированный анализ и проектирование. Часть 3. Объектная модель. Основные определения.

OOA and OOP При использовании той или иной методологии очень важно разговаривать с собеседниками на одном языке. Для этого нужно одинаково понимать термины, на основе которых строится общение или выражение собственной точки зрения.

В мире объектно-ориентированного анализа и проектирования также есть своя терминология и ключевые определения. Что такое ООП, что такое абстракция, что такое инкапсуляция и т.д. Всего определений огромное количество, поэтому в этом сообщении я ограничусь лишь основными, взятыми из главы 2. “Объектная модель” замечательной книги Гради Буча “Объектно-ориентированный анализ и проектирование с примерами приложений”.

Объектно-ориентированное программирование - это методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определенного класса, а классы образую иерархию наследования

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


Объектно-ориентированный анализ - это методология, при которой требования к системе воспринимаются с точки зрения классов и объектов, выявленных в предметной области.

Абстракция выделяет существенные характеристики некоторого объекта, отличающие его от всех других видов объектов и, таким образом, четко определяет его концептуальные границы с точки зрения наблюдателя.


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


Модульность - это свойство системы, которая была разложена на внутренне связные, но слабо связанные между собой модули.


Иерархия - это упорядочение абстракций, расположение их по уровням.


Типизация - это способ защититься от использования объектов одного класса вместо другого, или по крайней мере управлять таким использованием.


Параллелизм (concurrency) - это свойство, отличающее активные объекты от пассивных.


Сохраняемость (persistence) - способность объекта существовать во времени, переживая породивший его процесс, и (или) в пространстве, перемещаясь из своего первоначального адресного пространства.

четверг, 14 января 2010 г.

Алан Шаллоуей и Джеймс Р. Тротт. Шаблоны проектирования. Часть 1

Design Patterns Explained

В “природе” существует не такое большое количество книг по “классическим” шаблонам проектирования, впервые описанных в знаменитой книге Банды Четырех.

Одним из достойнейших представителей этой категории книг является книга Алана Шаллоуея и Джеймса Р. Тротта “Шаблоны проектирования. Новый подход к объектно-ориентированному анализу и проектированию”.

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

Множество ошибок появляется при внесении в текст программы изменений.
Попробуйте обосновать это утверждение исходя из собственного опыта. Вспомните, что всякий раз, когда в текст программы необходимо внести изменения, возникает опасение, что изменение текста программы в одном месте может привести к сбою в другом... Как это часто бывает с людьми, необходимость учесть при внесении изменений слишком много различных деталей обычно приводит к появлению ошибок.
Глава 1. Функциональная декомпозиция: в преддверии появления объектно-ориентированной парадигмы

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

Глава 1. Функциональная декомпозиция: в преддверии появления объектно-ориентированной парадигмы

Любой опрос среди разработчиков программного обеспечения по качеству предоставленных им заказчиком требований к создаваемому программному продукту едва ли даст большое разнообразие ответов. Скорее всего они будут следующими.
- Требования являются неполными.
- Требования по большей части ошибочны.
- Требования (и пользователи) противоречивы.
- Требования не описывают поставленную задачу подробно.

Глава 1. Проблема формулирования требований к создаваемому программному обеспечению

Требования к программному обеспечению всегда изменяются.
Я также понял, что большинство разработчиков знают это обстоятельство и считают его весьма неприятным. Но лишь немногие из них действительно учитывают возможность изменения существующих требований при написании программы.
Глава 1. Проблема формулирования требований к создаваемому программному обеспечению

Все это вовсе не значит, что можно опустить руки и отказаться от сбора полноценных требований пользователей к создаваемой системе. Напротив, это значит, что необходимо научиться приспосабливать создаваемый программный код к неизбежному внесению изменений. Это также значит, что необходимо прекратить обвинять себя (или заказчика) в том, что является совершенно закономерным.
Глава 1. Проблема формулирования требований к создаваемому программному обеспечению

 

Все цитаты из книги книги Алана Шаллоуейа и Джеймса Тротта “Шаблоны проектирования”:

Часть 1

Часть 2

Часть 3

Несколько слов о работе с заказчиком

вторник, 12 января 2010 г.

Объектно-ориентированный анализ и проектирование. Часть 2. Пять признаков сложных систем

OOA and OOP

Продолжая тему сложности, начатую в первой части цитат из замечательной книги Гради Буча “Объектно-ориентированный анализ и проектирование с примерами приложений”, я хочу отдельно опубликовать пять признаков сложных систем, которые, по мнению автора, присущи любой сложной системе.

 

 

 

1. "Сложные системы часто являются иерархическими и состоят из взаимозависимых подсистем, которые в свою очередь также могут быть разделены на подсистемы, и т.д., вплоть до самого низкого уровням."


2. Выбор, какие компоненты в данной системе считаются элементарными, относительно произволен и в большой степени оставляется на усмотрение исследователя.


3. "Внутрикомпонентная связь обычно сильнее, чем связь между компонентами. Это обстоятельство позволяет отделять "высокочастотные" взаимодействия внутри компонентов от "низкочастотной" динамики взаимодействия между компонентами".


4. "Иерархические системы обычно состоят из немногих типов подсистем, по-разному скомбинированных и организованных".


5. "Любая работающая сложная система является результатом развития работавшей более простой системы... Сложная система, спроектированная "с нуля", никогда не заработает. Следует начинать с работающей простой системы".

Объектно-ориентированный анализ и проектирование. Часть 1. Сложность

OOA and OOP

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

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

Я остановился именно на втором издании книги, а не на третьем, т.к. с моей точки зрения основную ценность представляет первая часть, которая осталась практически без изменений, а также потому что третье издание на русский язык лучше бы вообще не переводили (см. мои замечания по поводу перевода на rsdn.ru). Мое развернутое мнение – как обычно на блоге и на rsdn.ru.

В этом сообщении речь пойдет об одном из самых интересных аспектах разработки ПО – о сложности.

Врач, строитель и программистка спорили о том, чья профессия древнее. Врач заметил: "В Библии сказано, что Бог сотворил Еву из ребра Адама. Такая операция может быть проведена только хирургом, поэтому я по праву могу утверждать, что моя профессия самая древняя в мире". Тут вмешался строитель и сказал: "Но еще раньше в Книге Бытия сказано, что Бог сотворил из хаоса небо и землю. Это было первое и, несомненно, наиболее выдающееся строительство. Поэтому, дорогой доктор, вы не правы. Моя профессия самая древняя в мире". Программистка при этих словах откинулась в кресле и с улыбкой произнесла: "А кто же по-вашему сотворил хаос?"
Глава 1. Сложность


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

Сложность промышленных программ превышает возможности человеческого интеллекта. Увы, но сложность, о которой мы говорим, по-видимому, присуща всем большим программных системам. Говоря "присуща", мы имеем в виду, что эта сложность здесь неизбежна: с ней можно справиться, но избавиться от нее нельзя.
Глава 1.1. Простые и сложные программные системы

"Чем сложнее система, тем легче ее полностью развалить". Строитель едва ли согласится расширить фундамент уже построенного 100-этажного здания. Это не просто дорого: делать такие вещи значит напрашиваться на неприятности. Но что удивительно, пользователи программных систем, не задумываясь, ставят подобные задачи перед разработчиками. Это, утверждают они, всего лишь технический вопрос для программистов.
Глава 1.1. Последствия неограниченной сложности

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

Люди развили чрезвычайно эффективную технологию преодоления сложности. Мы абстрагируемся от нее. Будучи не в состоянии полностью воссоздать сложный объект, мы просто игнорируем не слишком важные детали и, таким образом, имеем дело с обобщенной, идеализированной моделью объекта.
Глава 1.3. Роль абстракции

понедельник, 4 января 2010 г.

Рефакторинг. Улучшение существующего кода. Часть 2

Refactoring

Обещанное продолжение цитат из замечательной книги Мартина Фаулера “Рефакторинг. Улучшение существующего кода”.

 

 

 

 

 

 

Если что-то плохо пахнет, это что-то надо поменять
                                 - Мнение бабушки Бек, высказанное
        при обсуждении проблем детского воспитания
Глава 3. Код с душком

Увидев одинаковые структуры кода в нескольких местах, можно быть уверенным, что если удастся их объединить, программа от этого только выиграет
Глава 3. Дублирование кода

Мы придерживаемся эвристического правила, гласящего, что если ощущается необходимость что-то прокомментировать, надо написать метод.
Глава 3. Длинный метод.

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

Брайан Фут (Brian Foote) предложил название "теоретическая общность" (speculative generality) для запаха, к которому мы очень чувствительны. Он возникает, когда говорят о том, что в будущем, наверное, потребуется возможность делать такие вещи, и хотят обеспечить набор механизмов для работы с вещами, которые не нужны. То, что получается в результате, труднее понимать и сопровождать. Если бы все эти механизмы использовались, их наличие было бы оправдано, в противном случае они только мешают, поэтому избавляйтесь от них.
Глава 3. Теоретическая общность

Цепочки сообщений появляются, когда клиент запрашивает у одного объекта другой, у которого клиент запрашивает еще один объект, у которого клиент запрашивает еще один объект и т.д. Это может выглядеть как длинный ряд методов getThis или последовательность временных переменных. Такие последовательности вызовов означают, что клиент связан с навигацией по структуре классов. Любые изменения промежуточных связей означают необходимость модификации клиента.
Глава 3. Цепочки сообщений

Почувствовав потребность написать комментарий, попробуйте сначала изменить структуру кода так, чтобы любые комментарии стали излишними.
Глава 3. Комментарии

Делайте все тесты полностью автоматическими, так чтобы они проверяли собственные результаты
Глава 4. Ценность самотестирующегося кода

Получив сообщение об ошибке, начните с создания теста модуля, показывающего эту ошибку.
Глава 4. Тесты модулей и функциональные тесты

Тестирование приносит ощутимую пользу, даже если осуществляется в небольшом объеме. Ключ к проблеме в том, чтобы тестировать те области, возможность ошибок в которых вызывает наибольшее беспокойство. При таком подходе затраты на тестирование приносят максимальную выгоду.
Глава 4. Добавление новых тестов

Лучше написать и выполнить неполные тесты, чем не выполнить полные тесты
Глава 4. Добавление новых тестов

Опасение по поводу того, что тестирование не выявит все ошибки, не должно помешать написанию тестов, которые выявят большинство ошибок.
Глава 4. Добавление новых тестов

Всегда есть риск что-то пропустить, но лучше потратить разумное время, чтобы выявить большинство ошибок, чем потратить вечность, пытаясь найти их все.
Глава 4. Добавление новых тестов

Маленькие методы действительно полезны, если выбирать для них хорошие имена. Иногда меня спрашивают, какой длины должно быть имя метода. Думаю, важна не длина, а семантическое расстояние между именем метода и телом метода. Если выделение метода делает код более понятным, выполните его, даже если имя метода окажется длиннее, чем выделенный код.
Глава 6. Выделение метода. Мотивировка.

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

Когда код имеет четкую структуру, часто находятся более мощные оптимизирующие решения, которые без рефакторинга остались бы незамеченными.
Глава 6. Замена временной переменной вызовом метода. Техника.

Все переменные, выполняющие несколько функций, должны быть заменены отдельной переменной для каждой из этих функций. Использование одной и той же переменной для решения разных задач очень затрудняет чтение кода.
Глава 6. Расщепление временной переменной. Мотивировка.

Я никогда не пробовал спать на потолке. Говорят, есть несколько способов. Наверняка одни из них легче, чем другие. С алгоритмами то же самое. Если обнаруживается более понятный способ сделать что-либо, следует заменить сложный способ простым.
Глава 6. Замещение алгоритма. Мотивировка.

Разумное и правильное проектное решение через неделю может оказаться неправильным. Но проблема не в этом, а в том, чтобы не оставить это без внимания.
Глава 7. Перемещение объекта. Мотивировка


Одним из ключевых свойств объектов является инкапсуляция. Инкапсуляция означает, что объектам приходится меньше знать о других частях системы. В результате при модификации других частей об этом требуется сообщить меньшему числу объектов, что упрощает внесение изменений.
Глава 7. Сокрытие делегирования. Мотивировка.

Важно внести ясность в смысл слова неизменяемый (immutable). Если есть класс, представляющий денежную сумму и содержащий тип валюты и величину, то обычно это объект с неизменяемым значением. Это не значит, что ваша зарплата не может измениться. Это значит, что для изменения зарплаты необходимо заменить существующий объект денежной суммы другим объектом денежной суммы, а не изменять значение в существующем объекте. Связь может измениться, но сам объект денежной суммы не изменяется.
Глава 8. Замена ссылки значением. Мотивировка.

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

Одна точка входа обеспечивается современными языками, а в правиле одной точки выхода на самом деле пользы нет. Ясность - главный принцип: если метод понятнее, когда в нем одна точка выхода, сделайте ее единственной, в противном случае не стремитесь к этому.
Глава 9. Замена вложенных условных операторов граничным оператором. Мотивировка.

В компьютерах, как и в жизни, иногда происходят неприятности, на которые надо как-то реагировать. Проще всего остановить программу и вернуть код ошибки. Это компьютерный эквивалент самоубийства из-за опоздания на самолет. Хотя я и пытаюсь снова шутить, но в решении компьютера о самоубийстве есть свои достоинства. Если потери от краха программы невелики, а пользователь терпелив, то можно и остановить программу. Однако в важных программах должны приниматься более радикальные меры.
Глава 10. Замена кода ошибки исключительной ситуацией. Мотивировка.

Преимущество исключительных ситуаций в том, что они четко отделяют нормальную обработку от обработки ошибок. Благодаря этому облегчается понимание программ, а создание понятных программ, как, я надеюсь, вы теперь верите, это достоинство, которое уступает только благочестию.
Глава 10. Замена кода ошибки исключительной ситуацией. Мотивировка.

Ральф Джонсон преподал мне важный урок, касающийся исследований: когда кто-то (рецензент статьи, участник конференции) заявляет, что он не понимает, или просто "не врубается", это наша вина. Наша обязанность постараться развить и донести свои идеи.
Глава 13. Проверка в реальных условиях

Это типичная дилемма исследователя, когда современное состояние науки опережает современное состояние практики.
Глава 13. Проверка в реальных условиях

Рефакторинг это ритм, а не отдельные ноты.
Как узнать, что вы действительно начали его понимать? Вы узнаете об этом, когда на вас снизойдет спокойствие. Когда вы почувствуете абсолютную уверенность, что как бы ни был закручен код, который вам достался, вы можете сделать его лучше, настолько лучше, чтобы развивать его дальше.
Глава 15. Складывая все вместе

Крупный рефакторинг - это способ навлечь на себя катастрофу. Каким бы ужасным ни выглядел беспорядок, приучите себя ограничиваться краями проблемы.
Глава 15. Складывая все вместе

Все цитаты из книги Мартина Фаулера “Рефакторинг. Улучшение существующего кода”.

Часть 1

Часть 2

Рефакторинг. Улучшение существующего кода. Часть 1

Refactoring С момента выхода оригинального издания этой книги прошло десять лет и уже давно понятия "рефакторинга" стало неотъемлемой частью арсенала каждого разработчика. Также уже довольно давно сбылась мечта авторов этой книги и поддержка рефакторинга уже не ограничивается единственной IDE для Smalltalk, а доступна практически в каждой современной IDE. Некоторые разработчики могут подумать, что в связи с этим ценность этой книги стала уменьшаться, но это не так. Главная ее ценность была и остается в том, что такое "код с душком", почему важно качество кода, какое влияние оказывает рефакторинг на процесс проектирования, какова роль модульных тестов, понять когда следует проводить рефакторинг, а когда от него вообще стоит отказаться и многое другое.
Поскольку цитат, как обычно для хорошей книги, набралось довольно много, то я разбил их на две части.
Итак, приступим, часть первая.

Компилятору все равно, красив код или нет. Но в процессе внесения изменений в систему участвуют люди, которым это не безразлично. Плохо спроектированную систему трудно модифицировать. Трудно потому, что нелегко понять, где изменения нужны. Если трудно понять, что должно быть изменено, то есть большая вероятность, что программист ошибется.
Глава 1. Комментарии к исходной программе

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

Перед началом рефакторинга убедитесь, что располагаете надежным комплектом тестов. Эти тесты должны быть самопроверяющимися.
Глава 1. Первый шаг рефакторинга

При применении рефакторинга программа модифицируется небольшими шагами. Ошибку нетрудно обнаружить.
Глава 1. Декомпозиция и перераспределение метода statement

Стоит ли заниматься переименованием? Без сомнения, стоит. Хороший код должен ясно сообщать о том, что он делает, и правильные имена переменных составляют основу понятного кода. Не бойтесь изменять имена, если в результате код становится более ясным.
Глава 1. Декомпозиция и перераспределение метода statement

Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям.
Глава 1. Декомпозиция и перераспределение метода statement

Очень важно, чтобы код сообщал о своей цели. Я часто провожу рефакторинг, когда просто читаю некоторый код. Благодаря этому свое понимание работы программы я отражаю в коде, чтобы впоследствии не забыть понятое.
Глава 1. Декомпозиция и перераспределение метода statement

Рефакторинг (Refactoring) (сущ.): изменение во внутренней структуре программного обеспечения, имеющее целью облегчить понимание его работы и упростить модификацию, не затрагивая наблюдаемого поведения.
Глава 2. Определение рефакторинга

Цель рефакторинга - упростить понимание и модификацию программного обеспечения
Глава 2. Определение рефакторинга

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

Беда в том, что когда вы бьетесь над тем, чтобы заставить программу работать, то совсем не думаете о разработчике, который будет заниматься ею в будущем. Надо сменить ритм, чтобы внести в код изменения, облегчающие его понимание. Рефакторинг помогает сделать код более легким для чтения.
Глава 2. Рефакторинг облегает понимание программного обеспечения

Я не считаю себя замечательным программистом. Я просто хороший программист с замечательными привычками
Высказывание Кента Бека
Глава 2. Рефакторинг помогает найти ошибки

Как правило, я против откладывания рефакторинга "на потом". На мой взгляд, это не тот вид деятельности. Рефакторингом следует заниматься постоянно понемногу. Надо не решать проводить рефакторинг, а проводить его, потому что необходимо сделать что-то еще, а поможет в этом рефакторинг.
Глава 2. Когда следует проводить рефакторинг?

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

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

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

В некоторых случаях рефакторинг вообще не нужен. Основной пример - необходимость переписать программу с нуля. Иногда имеющийся код настолько запутан, что подвергнуть его рефакторингу, конечно, можно, но проще начать все с самого начала.
Глава 2. Когда рефакторинг не нужен?

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

Рефакторинг позволяет создавать более простые проекты, не жертвуя гибкостью, благодаря чему процесс проектирования становится более легким и менее напряженным. Научившись в целом распознавать то, что легко поддается рефакторингу, о гибкости решений даже перестаешь задумываться. Появляется уверенность в возможности применения рефакторинга, когда это понадобится. Создаются самые простые решения, которые могут работать, а гибкие и сложные решения по большей части не потребуются.
Глава 2. Проектирование и рефакторинг

Секрет создания быстрых программ, если только они не предназначены для работы в жестком режиме реального времени, состоит в том, чтобы сначала написать программу, которую можно настраивать, а затем настроить ее так, чтобы достичь приемлемой скорости.
Глава 2. Рефакторинг и производительность

Хорошее разделение программы на компоненты способствует оптимизации такого рода в двух отношениях. Во-первых, благодаря ему появляется время, которое можно потратить на оптимизацию. Имея хорошо структурированный код, можно быстрее добавлять новые функции и выиграть время для того, заняться производительностью. (Профилирование гарантирует, что это время не будет потрачено зря.) Во-вторых, хорошо структурированная программа обеспечивает более высокое разрешение для анализа производительности. Профайлер указывает на более мелкие фрагменты кода, которые легче настроить. Благодаря большей понятности кода лекче осуществить выбор возможных вариантов и разобраться в том, какого рода настройка может оказаться действенной.
Глава 2. Рефакторинг и производительность

Все цитаты из книги Мартина Фаулера “Рефакторинг. Улучшение существующего кода”.

Часть 1

Часть 2

воскресенье, 13 декабря 2009 г.

Программист-прагматик. Часть 4. Проектирование

Проблема сцепления (cohesion) и связности (coupling) беспокоит архитекторов в самых различных областях уже много лет; в области разработки ПО эта тема поднималась еще Эдвардом Йордоном и Ларри Константайном тридцать лет назад. И хотя тема построения слабосвязного ПО не является единственной темой по проектированию ПО, именно она проходит красной нитью через всю книгу “Программист-прагматик”.

Термин «ортогональность» заимствован из геометрии. Две линии являются ортогональными, если они пересекаются под прямым углом, например оси координат на графике. В терминах векторной алгебры две такие линии являются независимыми. Если двигаться вдоль одной из линий, то проекция движущейся точки на другую линию не меняется.
Этот термин был введен в информатике для обозначения некой разновидности независимости или несвязанности. Два или более объекта ортогональны, если изменения, вносимые в один из них, не влияют на любой другой.
Глава 2. Что такое ортогональность?

Ничто не вечно, и если вы всерьез полагаетесь на некоторое явление, то этим вы практически гарантируете, что оно непременно изменится.
Глава 2. Обратимость

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

Перед тем как вы займетесь созданием любого прототипа, основанного на программе, убедитесь, что все понимают – вы пишите одноразовую программу. Прототипы могут быть обманчиво привлекательными для людей, которые не знаю, что это всего лишь прототипы. Вы должны очень четко уяснить – эта программа одноразовая, незавершенная и не может быть завершена.
Легко впасть в заблуждение из-за очевидной завершенности демонстрационного прототипа, и спонсоры проекта или менеджмент могут настаивать на развертывании прототипа (или его потомства), если вы заранее не определите, что можно ожидать от прототипа. Напомните им, что вы, конечно, можете создавать великолепный прототип новой модели автомобиля из бальзовой древесины и клейкой ленты, но вы же не поедете на нем в час пик!

Глава 2. Как не надо использовать прототипы

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

Глава 5. Гибкость против хрупкости

Шпионы, диссиденты, революционеры и им подобные часто организованы в небольшие группы, называемые ячейками. Хотя отдельные личности в каждой ячейке могут знать друг о друге, они не знают ничего об участниках других ячеек. Если одна ячейка раскрыта, то никакое количество "сыворотки правды" неспособно выбить из ее участников информацию об их сподвижниках вне пределов ячейки. Устранение взаимодействий между ячейками убережет всех.
Мы полагаем, что этот принцип хорошо бы применить и к написанию программ. Разбейте вашу программу на ячейки (модули) и ограничьте взаимодействие между ними. Если один модуль находится под угрозой и должен быть заменен, то другие модули должны быть способны продолжить работу.

Глава 5. Несвязанность и закон Деметера

Когда мы запрашиваем у объекта определенную услугу, то мы хотим, что бы эта услуга оказывалась от нашего имени. Мы не хотим, чтобы данный объект предоставлял нам еще какой-то объект, подготовленный третьей стороной, с которым нам придется иметь дело для получения необходимой услуги.
Глава 5. Сведение связанности к минимуму

Все цитаты из книги Дейва Томаса и Энди Ханта “Программист-прагматик. Путь от подмастерья к мастеру”:

Часть 1. Философия программирования

Часть 2. Дублирование информации

Часть 3. Инструменты

Часть 4. Проектирование

Часть 5. Тестирование и отладка

Часть 6. Управление проектами