Закон сохранения сложности
От: Игорь Ткачёв Россия linq2db.com
Дата: 19.07.09 23:47
Оценка: 1976 (61) +7 -5
Статья:
Закон сохранения сложности
Автор(ы): Игорь Ткачёв
Дата: 06.12.2002


Авторы:
Игорь Ткачёв

Аннотация:
Существует множество практик, принципов, паттернов и прочих страшных слов, которые мы используем в нашей повседневной профессиональной деятельности и очень часто даже не задаём себе вопрос зачем мы это делаем. Зачем это всё нужно, плохо это или хорошо, когда плохо и когда хорошо. Зачем нужны все эти принципы? На самом деле ответ до банального очевиден. Всё это в конце концов направлено на борьбу со сложностью разработки ПО. Теперь пришла очередь задать вопрос — а что же такое сложность и как знание того что это такое поможет нам лучше понять и использовать принципы, которые как раз и направлены на борьбу с ней?
Если нам не помогут, то мы тоже никого не пощадим.
Re: Закон сохранения сложности
От: Lloyd Россия  
Дата: 20.07.09 00:31
Оценка:
Здравствуйте, Игорь Ткачёв, Вы писали:

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


Статья себе противоречит:

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


Следовательно, если мы не будем пытаться "заранее выделить код", то взамен ничего не потеряем, сложность уменьшим.
Следовательно, утверждение "устраняя сложность в одном месте мы всегда добавляем её где-то в другом" — неверно.
Следовательно, законом сохранения сложности и не закон вовсе.
Re[2]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 03:49
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Статья себе противоречит:


Там же в самом начале написано — сложность штука противоречивая. Это было написано специально для таких как ты.

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


Если ты не будешь пытаться, то ничего ни не потеряешь, ни не уменьшишь.

L>Следовательно, утверждение "устраняя сложность в одном месте мы всегда добавляем её где-то в другом" — неверно.


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

L>Следовательно, законом сохранения сложности и не закон вовсе. ;)


— Суслика видишь?
— Нет.
— А он есть!
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Закон сохранения сложности
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.07.09 04:46
Оценка:
Здравствуйте, Lloyd, Вы писали:

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

Противоположность увеличения сложности — неувеличение, а не строгое уменьшение. Поэтой при нулевых поползновениях сложность не изменится.
Re: Закон сохранения сложности
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.07.09 05:21
Оценка:
Здравствуйте, Игорь Ткачёв, Вы писали:

ИТ>Статья:

ИТ>Закон сохранения сложности
Автор(ы): Игорь Ткачёв
Дата: 06.12.2002



1)Сложность восприятия и сложность обучения — практичеки одно и тоже, только взгляд с разных сторон.
2)Сложность восприятия, сложность обучения, количественная сложность — их преодоление является разовыми затратами, тогда как алгоритмическая сложность и сложность сложность изменения преслдуют постоянно.
3)Пониятие алгоритмической сложности слишком обобщено. Напрмиер разработка парсера языка и трехзвенной бухгалтерской системы обладают высокой сложностью, но причины сложности совершенно разные.
Re[2]: Закон сохранения сложности
От: mrTwister Россия  
Дата: 20.07.09 06:22
Оценка: +1
Здравствуйте, gandjustas, Вы писали:

G>2)Сложность восприятия, сложность обучения, количественная сложность — их преодоление является разовыми затратами


В общем случае, это неверно. Лично я забываю всякую ерунду очень быстро, и, как следствие, приходится помногу раз вникать в один и тот же проект. Соответственно, чем выше порог вхождения, тем больше тратится ресурсов на "переключение контекста" между проектами.
лэт ми спик фром май харт
Re[3]: Закон сохранения сложности
От: Lloyd Россия  
Дата: 20.07.09 07:10
Оценка:
Здравствуйте, IT, Вы писали:

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


IT>Если ты не будешь пытаться, то ничего ни не потеряешь, ни не уменьшишь.


Переход от решения A в котором "мы пытаемся заранее выделить код, который по идее можно повторно использовать" к решению B, в котором не было предпринято такой попытки, судя по постановке должно привести в уменьшению сложности. Разве не так?
Re[3]: Закон сохранения сложности
От: Lloyd Россия  
Дата: 20.07.09 07:15
Оценка:
Здравствуйте, gandjustas, Вы писали:

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

G>Противоположность увеличения сложности — неувеличение, а не строгое уменьшение. Поэтой при нулевых поползновениях сложность не изменится.

Тут не термодинамика, тут любой процесс можно повернуть вспять и очень легко — окрываешь сорсконтрол и делаешь Revert Changes. И если в ревизии 101 у тебя при прочих равных сложность выше, чем в ревизии 100, то откатившись на 100-ю ревизию получишь уменьшение сложности, которого по мнению автора статьи "не существует".
Re[3]: Закон сохранения сложности
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.07.09 07:36
Оценка: +2 :)
Здравствуйте, mrTwister, Вы писали:

T>Здравствуйте, gandjustas, Вы писали:


G>>2)Сложность восприятия, сложность обучения, количественная сложность — их преодоление является разовыми затратами


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


Если часто надо переключаться между проектами, то это хреновый менеджемнт и сложности не относится.
Re[4]: Закон сохранения сложности
От: WolfHound  
Дата: 20.07.09 08:02
Оценка: -1
Здравствуйте, Lloyd, Вы писали:

L>Переход от решения A в котором "мы пытаемся заранее выделить код, который по идее можно повторно использовать" к решению B, в котором не было предпринято такой попытки, судя по постановке должно привести в уменьшению сложности. Разве не так?

Это зависит от того было ли в решении А повторное использование кода или нет.
Если было то решение В сложнее, а если не было то решение В проще.
Ибо превращение кода в повторно используемый всегда приводит к его усложнению.
Упрощение происходит только тогда когда мы несколько раз повторно используем этот код.
И если мы по факту не смогли этот код использовать повторно то мы добавили сложность в одном месте и не убрали в другом.

Таким образом приходим к эвристике: Превращай код в повторно используемый только после того как он понадобился повторно.

Конечно бывают случаи когда точно известно что код будет использован повторно но если 100%ной уверенности нет то см эвристику.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[5]: Закон сохранения сложности
От: Cyberax Марс  
Дата: 20.07.09 08:07
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Таким образом приходим к эвристике: Превращай код в повторно используемый только после того как он понадобился повторно.

Ага, и если так не делать, то приложения превращаются в набор "повторно используемого кода", который не может быть повторно использован.
Sapienti sat!
Re[2]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 13:46
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>1)Сложность восприятия и сложность обучения — практичеки одно и тоже, только взгляд с разных сторон.


Сложность само по себе одно и тоже — затраченные усилия, и её виды — это как раз и есть взгляд с разных сторон. Разделение на виды само по себе вещь достаточно условная и интересно прежде всего для выявления, лучшего понимания и устранения проблемных мест. Возьмём, например, код, который плохо читаем, т.к. страдает отсутствием форматирования, соглашений, запутан и многословен. Что нужно сделать, чтобы он стал прощё? Его можно отформатировать, отрефакторить, распутать и убрать лишнее. В результате он станет проще за счёт уменьшения сложности восприятия. Теперь возьмём код, который легко читается, но базируется на технологии, которая изучающему этот код пока не известна. Пусть это будет WPF — как раз та вещь, которая обладает довольно высоким порогом вхождения. Поможет ли нам форматирование кода, его рефакторинг и распутывание лучше понять такой код? Ответ очевиден — не поможет, рефакторить можно хоть до посинения. Нужно брать в руки книжки и изучать технологию.

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


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

G>3)Пониятие алгоритмической сложности слишком обобщено. Напрмиер разработка парсера языка и трехзвенной бухгалтерской системы обладают высокой сложностью, но причины сложности совершенно разные.


Какие?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 13:51
Оценка:
Здравствуйте, Lloyd, Вы писали:

IT>>Если ты не будешь пытаться, то ничего ни не потеряешь, ни не уменьшишь.


L>Переход от решения A в котором "мы пытаемся заранее выделить код, который по идее можно повторно использовать" к решению B, в котором не было предпринято такой попытки, судя по постановке должно привести в уменьшению сложности. Разве не так?


Не так. Давай возьмём для примера следующий код:

var a = b + c;

Предположим, что мы можем здесь выделить операцию сложения в отдельный метод. Но мы этого не стали делать. До того как мы этого не стали делать у нас было a = b + c, а после того как мы этого не сделали у нас стало a = b + c. Было a = b + c, стало a = b + c. За счёт чего второе a = b + c, стало проще первого?
Если нам не помогут, то мы тоже никого не пощадим.
Re: Закон сохранения сложности
От: mkizub Литва http://symade.tigris.org
Дата: 20.07.09 13:54
Оценка: 1 (1) +1
Здравствуйте, Игорь Ткачёв, Вы писали:

Понятием "сложность" занимается кибернетика. В частности, из возрастающей сложности управляемой системы она выводит необходимость иерарихии управляющих (под)систем. То-же самое происходит при создании софта, при этом программисты создают иерархию уровней абстракции. Собственно, она и решает те проблемы, о которых написано в статье. И приёмы уменьшения разных типов сложности (алгоритмическая сложноть, сложность восприятия и пр.) в целом тоже укладываются в эти уровни абстракции. Мы говорим о более или менее высокоуровневых языках программирования, фреймворках и т.п.

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

Так бы и продолжалось дальше, но увы, экспоненциальное развитие скорости компьютеров практически закончилось. И просто увеличение количества уровней абстракции (вроде применения более высокоуровневых языков программирования) уже не поможет — железо не потянет. И выход тут я вижу только один — использовать компьютер. Он не имеет такого встроенного ограничения на уровень сложности программы, которую должен анализировать. Но увы, он не имеет и интеллекта, чтоб писать и анализировать программы. Вот когда этот интеллект у него появится — тогда и появится реальная альтернатива увеличению количества уровней абстракции в программе. Чтоб программы становились более сложными и функциональными, без экспоненциального увеличения требований к ресурсам.
SOP & SymADE: http://symade.tigris.org , блог http://mkizub.livejournal.com
Re[2]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 14:20
Оценка:
Здравствуйте, mkizub, Вы писали:

M>И выход тут я вижу только один — использовать компьютер.


Я вижу (и в какой-то мере уже использую) ещё один — метапрограммирование.
Если нам не помогут, то мы тоже никого не пощадим.
Re[3]: Закон сохранения сложности
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 20.07.09 15:49
Оценка:
Здравствуйте, IT, Вы писали:

IT>Здравствуйте, gandjustas, Вы писали:


G>>1)Сложность восприятия и сложность обучения — практичеки одно и тоже, только взгляд с разных сторон.


IT>Сложность само по себе одно и тоже — затраченные усилия, и её виды — это как раз и есть взгляд с разных сторон. Разделение на виды само по себе вещь достаточно условная и интересно прежде всего для выявления, лучшего понимания и устранения проблемных мест. Возьмём, например, код, который плохо читаем, т.к. страдает отсутствием форматирования, соглашений, запутан и многословен. Что нужно сделать, чтобы он стал прощё? Его можно отформатировать, отрефакторить, распутать и убрать лишнее. В результате он станет проще за счёт уменьшения сложности восприятия.

Этот рефакторинг выполняется автоматически и занимает минимум времени. Гораздо больше займет собственно понимание что делает код.

IT>Теперь возьмём код, который легко читается, но базируется на технологии, которая изучающему этот код пока не известна. Пусть это будет WPF — как раз та вещь, которая обладает довольно высоким порогом вхождения. Поможет ли нам форматирование кода, его рефакторинг и распутывание лучше понять такой код? Ответ очевиден — не поможет, рефакторить можно хоть до посинения. Нужно брать в руки книжки и изучать технологию.

Понимание что делает код не появится без понимания абстракций, которыми он оперирует.

Так что для "восприятия" нужно "обучение".

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


IT>Это смотря как посмотреть. Плохо читаемый и многословный код придётся преодолевать каждый раз, когда он будет читаться.

Один программист читает код один раз когда разбирается как он работает.

IT>Сложность обучения придётся преодолевать каждому новому бойцу в команде, для которого порог вхождения в код выше его текущего предела.

Это еще более редкое явление.

Преодоление этих сложностей требует гораздо меньших затрат по сравнению с преодолением сложности изменений при постоянном развитии проекта.

G>>3)Пониятие алгоритмической сложности слишком обобщено. Напрмиер разработка парсера языка и трехзвенной бухгалтерской системы обладают высокой сложностью, но причины сложности совершенно разные.

IT>Какие?
В случае парсера — нетривиальные алгоритмы — неочевидное преобразование входных данных в выходные, которое вряд ли получится декомпозировать на более протые части. В случае бухгалтерской системы все можно до элементарных вещей декопозировать, но возникает пролема распределения обязанностей между программными модулями и обеспечение их взаимодействия.
Re[4]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 16:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Этот рефакторинг выполняется автоматически и занимает минимум времени. Гораздо больше займет собственно понимание что делает код.


Это зависит от кода. Можно так написать, что простой в понимании код вообще не будет читаться, а его рефакторинг займёт гораздо больше времени, чем его понимание. В общем, без конкретного кода я не стал бы даже это обсуждать.

G>Так что для "восприятия" нужно "обучение".


Возможно термин восприятие не очень удачен, но в моём определении важно как раз то, что он отделён от обучения и относится к форме кода, а не его содержанию. Если у тебя есть более точное определение предлагай.

IT>>Сложность обучения придётся преодолевать каждому новому бойцу в команде, для которого порог вхождения в код выше его текущего предела.

G>Это еще более редкое явление.

G>Преодоление этих сложностей требует гораздо меньших затрат по сравнению с преодолением сложности изменений при постоянном развитии проекта.


Опять же это всё зависит от конкретного рассматриваемого случая. В моей команде используется всё, что сегодня доступно на рынке мэйнстрима: последние версии компиляторов и их новые возможности, последние технологии и т.д. Это позволяет нам перераспределить сложность наших проектов в сложность обучения и контролировать наш код малым числом людей. Я не возьму на работу человека далёкого от всего этого, например, такого, который застыл на уровен .NET 1.1. Не возьму по простой причине — затраты на его обучение не будут, как ты утверждаешь, меньше по сравнению с преодолением других видов сложности. Они будут значительно больше, и если это будет контрактник на 10 месяцев, то за это время он не успеет сделать ничего полезного.

G>>>3)Пониятие алгоритмической сложности слишком обобщено. Напрмиер разработка парсера языка и трехзвенной бухгалтерской системы обладают высокой сложностью, но причины сложности совершенно разные.

IT>>Какие?
G>В случае парсера — нетривиальные алгоритмы — неочевидное преобразование входных данных в выходные, которое вряд ли получится декомпозировать на более протые части. В случае бухгалтерской системы все можно до элементарных вещей декопозировать, но возникает пролема распределения обязанностей между программными модулями и обеспечение их взаимодействия.

Я думал об этом и пока не могу однозначено разделить две вещи: уровень интеллекта и способность удерживать в голове целиком задачу определённого размера. Мне кажется это суть одно и тоже, но, возможно, я не прав. Было бы интересно обсужить эти вещи подробнее.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: Закон сохранения сложности
От: Lloyd Россия  
Дата: 20.07.09 17:22
Оценка: -1
Здравствуйте, IT, Вы писали:

IT>Не так. Давай возьмём для примера следующий код:


IT>
IT>var a = b + c;
IT>

IT>Предположим, что мы можем здесь выделить операцию сложения в отдельный метод. Но мы этого не стали делать. До того как мы этого не стали делать у нас было a = b + c, а после того как мы этого не сделали у нас стало a = b + c. Было a = b + c, стало a = b + c. За счёт чего второе a = b + c, стало проще первого?

Предлагаю рассмотреть другой вариант.
Было var a = b + c; его отрефактирили в var a = Add(b, c);
Если мы теперь вернемся к первоначальному var a = b + c;, то получим решение, которое проще (чем var a = Add(b, c)).
Т.е получаем уменьшение сложности.

Я это имел в виду.
Re[6]: Закон сохранения сложности
От: IT Россия linq2db.com
Дата: 20.07.09 17:35
Оценка: +1
Здравствуйте, Lloyd, Вы писали:

L>Предлагаю рассмотреть другой вариант.

L>Было var a = b + c; его отрефактирили в var a = Add(b, c);
L>Если мы теперь вернемся к первоначальному var a = b + c;, то получим решение, которое проще (чем var a = Add(b, c)).
L>Т.е получаем уменьшение сложности.

Уменьшение по сравнению с чём? Исходную сложность ты не уменьшил, а излишнюю да, устранил. Или вот ещё:

if (a == true)
{
    return true;
}
else if (a == false)
{
    return false;
}
else if (a != true && a != false)
{
    throw new ApplicationException()
}

такой код упрощается до:

return a;

при этом сложность этого кода уменьшается. Но начальная сложность никуда не делась. Если задача ставится как, например, умножить два числа, то можно применить множество практик и техник, но умножение или заменяющий его алгоритм в том или ином виде в коде присутствовать должен. От этого никуда не деться и это указано в статье.

L>Я это имел в виду.


Возможно не все формулировки и объяснения получились достаточно чёткими и однозначными. Я над этим работаю
Если нам не помогут, то мы тоже никого не пощадим.
Re: нет такого закона.
От: goldblueranger  
Дата: 20.07.09 19:59
Оценка: 42 (5) +1
Законы сохранения действуют в обоих направлениях, соответственно, если бы такой закон был, то при искусственном увеличении сложности в реализации какой-то функции, сложность чего-то другого уменьшалась бы.

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

Например, вместо применения формулы для решения квадратного уровнения можн онаписать подсистему, которая будет рисовать параболу, сохраняь в BMP формате, потом парсить пикселы из файла и находить приблизительное решение по точкам пересечения. Можно еще написать свой архиватор "для компактного хранения этих BMP" и драйвер HDD который будет оптимально хранить полученый архив на диске. Эти операции — многократное увеличение сложности по сравнению с вычислением дискриминанта, при этом только увеличивается (что опровергает гипотезу о законе).

Или я что-то не понял?

А вообще респект за тему — управление сложностью — самое важное в разработке.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.