Re: Закон сохранения сложности
От: MozgC США http://nightcoder.livejournal.com
Дата: 27.07.09 15:02
Оценка: 83 (4)
Хорошая и важная статья. Только мне кажется что некоторые читатели могут после прочтения сделать неверные выводы, и решить что раз сложность никуда не девается, то и делать ничего не нужно. Тем не менее это неверно. Со сложностью надо бороться и всегда стараться свести ее к минимуму. Макконнелл в своей книге называет управление сложностью — главным техническим аспектом разработки ПО:

Важность управления сложностью

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

Управление сложностью — самый важный технический аспект разработки ПО. По-моему, управление сложностью настолько важно, что оно должно быть Главным Техническим Императивом Разработки ПО.

Сложность — не новинка в мире разработки ПО. Один из пионеров информатики Эдсгер Дейкстра обращал внимание на то, что компьютерные технологии — единственная отрасль, заставляющая человеческий разум охватывать диапазон, простирающийся от отдельных битов до нескольких сотен мегабайт информации, что соответствует отношению 1 к 109, или разнице в девять порядков (Dijkstra, 1989).
Такое гигантское отношение просто ошеломляет. Дейкстра выразил это так: «По сравнению с числом семантических уровней средняя математическая теория кажется почти плоской. Создавая потребность в глубоких концептуальных иерархиях, компьютерные технологии бросают нам абсолютно новый интеллектуальный вызов, не имеющий прецедентов в истории». Разумеется, за прошедшее с 1989 г. время
сложность ПО только выросла, и сегодня отношение Дейкстры вполне может характеризоваться 15 порядками. Дейкстра пишет, что ни один человек не обладает интеллектом, способным вместить все детали современной компьютерной программы (Dijkstra, 1972), поэтому нам — разработчикам ПО — не следует пытаться охватить всю программу сразу. Вместо этого мы должны попытаться организовать программы так, чтобы можно было безопасно работать с их отдельными фрагментами по очереди. Целью этого является минимизация объема программы, о котором нужно думать в конкретный момент времени. Можете считать это своеобразным умственным жонглированием: чем больше умственных шаров программа заставляет поддерживать в воздухе, тем выше вероятность того, что вы уроните один из них и допустите ошибку при проектировании или кодировании.
На уровне архитектуры ПО сложность проблемы можно снизить, разделив систему на подсистемы. Несколько несложных фрагментов информации понять проще, чем один сложный. В разбиении сложной проблемы на простые фрагменты и заключается цель всех методик проектирования ПО. Чем более независимы подсистемы, тем безопаснее сосредоточиться на одном аспекте сложности в конкретный момент времени. Грамотно определенные объекты разделяют аспекты проблемы так, чтобы вы могли решать их по очереди. Пакеты обеспечивают такое же преимущество на более высоком уровне агрегации.
Стремление к краткости методов программы помогает снизить нагрузку на интеллект. Этому же способствует написание программы в терминах проблемной области, а не низкоуровневых деталей реализации, а также работа на самом высоком уровне абстракции.
Суть сказанного в том, что программисты, компенсирующие изначальные ограничения человеческого ума, пишут более понятный и содержащий меньшее число ошибок код.

Как бороться со сложностью?
Чаще всего причинами неэффективности являются:
— сложное решение простой проблемы;
— простое, но неверное решение сложной проблемы;
— неадекватное сложное решение сложной проблемы.

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


Кстати, думаю что стоит обратить внимание и на сложность требований, приводящих к резкому увеличению сложности разрабатываемого ПО. Считается, что увеличение сложности задачи на 25% приводит к усложнению программного решения на 100% (Факты и заблуждения профессионального программирования (с) Роберт Гласс):

Факт 21
Увеличение сложности задачи на 25% приводит к усложнению программного решения на 100%, Это не условие, которое можно попытаться изменить (хотя сложность всегда желательно свести к минимуму), это реальное положение дел.


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