Представьте, что перед вами стоит задача. Вы сначала попытаетесь воплотить её на самом простом и эффективном из доступных вам средств/языков (грубо говоря: написать на C, хотя и не обязательно, я сейчас не о конкретных языках а о принципе) и только если станет ясно, что запутываетесь и реально нужны более сложные средства (скажем очевидно, что ООП сильно помогло бы или вообще без сборки мусора явно плохо), примените их или наоборот сначала быстро решите её пусть даже с большим оверхедом на самом навороченном из доступных средств? Для чистоты эксперимента предположим что у вас идеальные условия -- время не давит, начальство всем довольно, заказчики с кровавыми топорами к двери кабинета не подкрадываются. Лично я встречал людей, которые эффективно пишут хороший код и по первому и по второму принципам. И я видел откровенно никчёмный код написанный и так и так.
Но в защиту первого принципа у меня есть очень как мне кажется веский аргумент и имя ему -- повторное использование. Модуль написанный на чистом C вы сможете использовать на любом проекте. Модуль написанный на C++ с исключениями и STL вы сможете использовать повторно только если у вас на проекте есть STL и разрешены исключения. Модуль, написанный на C++/CLI вы сможете использовать только если в проекте разрешен .Net (хотя бы в виде CLR-хостинга) и т.д. То есть чем более мощные и удобные средства вы использовали при написании кода, тем ниже шансы его повторно использовать.
Ещё хуже -- *иллюзия* возможности реюза, которую дают классы. Вы наследуетесь от кого-то, первый месяц всё идёт хорошо, а потом вы упираетесь в нечто неожиданное внутри этого класса и приходится писать убогие подставки и костыли. Лично я уже очень давно и основательно боюсь излишнего наследования -- простое использование хорошо написанного чужого класса кажется более безопасным и то только если покрыть юнит-тестами вдоль и поперёк.
Отдельная песня -- повторное использование на бинарном уровне. Unmanaged-DLL в которой наружу выставляются функции C-интерфейса (а лучше если ещё и stdcall) может быть использована в пределах Win32 кем угодно и мне даже из managed-кода не возникало никогда проблем такие задействовать. Сложнее если наружу торчат классы. Ещё сложнее если это внутрипроцессный COM-сервер. Я скромно молчу про Java и .Net в этом отношении -- там наличие чего-то, что вы хотите повтрно использовать написанного на данном фреймворке *и уже собранного* по сути привязывает вас к фреймворку.
Ещё более интересный вопрос -- самодисциплина. Но это уже индивидуально и холиворно.
Вот интересно, это мне просто сильно не везло в жизни с тем, что я пытался реюзать или это у всех после некоторого опыта наступает такой период?
P.S. Я не говорю здесь об оптимизации. Решение простыми средствами может быть и не очень оптимальным, если это предполагает скажем самописный malloc и memcpy (да, бывает и такое если CRT запрещён). Оптимизация ясное дело всегда на потом. Исключительно о простоте используемых средств.
P.P.S. Ссылки на статьи и литературу философски-практического плана очень приветствуются. Буча, Страуструпа, Александреску, Фаулера и GoF читал.
Здравствуйте, Tilir, Вы писали:
T>Представьте, что перед вами стоит задача. Вы сначала попытаетесь воплотить её на самом простом и эффективном из доступных вам средств/языков (грубо говоря: написать на C, хотя и не обязательно, я сейчас не о конкретных языках а о принципе) и только если станет ясно, что запутываетесь и реально нужны более сложные средства (скажем очевидно, что ООП сильно помогло бы или вообще без сборки мусора явно плохо), примените их или наоборот сначала быстро решите её пусть даже с большим оверхедом на самом навороченном из доступных средств? Для чистоты эксперимента предположим что у вас идеальные условия -- время не давит, начальство всем довольно, заказчики с кровавыми топорами к двери кабинета не подкрадываются. Лично я встречал людей, которые эффективно пишут хороший код и по первому и по второму принципам. И я видел откровенно никчёмный код написанный и так и так.
В идеальном случае все равно как писать. Собственно неидеальность мира и приводит к прогрессу, в том числе и в сфере разработки ПО.
В реальном случае все зависит от задачи.
Как-то раз я писал патчер для бинарников на ассемблере вместе с UI. Если требуется работа с БД, то лучше использовать .NET.
Как всегда эффективность решения зависит от сочетания задачи, языка и программиста.
T>Но в защиту первого принципа у меня есть очень как мне кажется веский аргумент и имя ему -- повторное использование. Модуль написанный на чистом C вы сможете использовать на любом проекте. Модуль написанный на C++ с исключениями и STL вы сможете использовать повторно только если у вас на проекте есть STL и разрешены исключения. Модуль, написанный на C++/CLI вы сможете использовать только если в проекте разрешен .Net (хотя бы в виде CLR-хостинга) и т.д. То есть чем более мощные и удобные средства вы использовали при написании кода, тем ниже шансы его повторно использовать.
Но для .NET можно писать на куче языков и выбирать тот, что наиболее подходит.
Немного переформулирую тезис: "написать на .NET языке повторно используемый модуль гораздо легче".
T>Ещё хуже -- *иллюзия* возможности реюза, которую дают классы. Вы наследуетесь от кого-то, первый месяц всё идёт хорошо, а потом вы упираетесь в нечто неожиданное внутри этого класса и приходится писать убогие подставки и костыли. Лично я уже очень давно и основательно боюсь излишнего наследования -- простое использование хорошо написанного чужого класса кажется более безопасным и то только если покрыть юнит-тестами вдоль и поперёк.
Это касается любого чужого кода вообще. И использовать наследование везде — не лучшая практика.
T>Отдельная песня -- повторное использование на бинарном уровне. Unmanaged-DLL в которой наружу выставляются функции C-интерфейса (а лучше если ещё и stdcall) может быть использована в пределах Win32 кем угодно и мне даже из managed-кода не возникало никогда проблем такие задействовать. Сложнее если наружу торчат классы. Ещё сложнее если это внутрипроцессный COM-сервер. Я скромно молчу про Java и .Net в этом отношении -- там наличие чего-то, что вы хотите повтрно использовать написанного на данном фреймворке *и уже собранного* по сути привязывает вас к фреймворку.
У COM повтораная используемость выше. Можно написать COM объект на javascript и использовать его на C. Причем объект будет находиться на другом машине.
Учитывая что на .NET можно писать COM объекты, то возможностей повторно использовать .NET библиотеку горазо больше.
Здравствуйте, Tilir, Вы писали:
T>Ещё хуже -- *иллюзия* возможности реюза, которую дают классы. Вы наследуетесь от кого-то, первый месяц всё идёт хорошо, а потом вы упираетесь в нечто неожиданное внутри этого класса и приходится писать убогие подставки и костыли. Лично я уже очень давно и основательно боюсь излишнего наследования -- простое использование хорошо написанного чужого класса кажется более безопасным и то только если покрыть юнит-тестами вдоль и поперёк.
Один из известных Lisp-оводов, Ричард Гэбриель, считает, что наследование -- это не повторное использование, а компрессия (сжатие) кода. О чем он написал небольшое эссе в своей книге Patterns of Software. Tales from the Software Community. На русском это эссе можно найти здесь (PDF, ~140Kb).
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Tilir, Вы писали:
T>Представьте, что перед вами стоит задача. Вы сначала попытаетесь воплотить её на самом простом и эффективном из доступных вам средств/языков (грубо говоря: написать на C, хотя и не обязательно, я сейчас не о конкретных языках а о принципе) и только если станет ясно, что запутываетесь и реально нужны более сложные средства (скажем очевидно, что ООП сильно помогло бы или вообще без сборки мусора явно плохо), примените их или наоборот сначала быстро решите её пусть даже с большим оверхедом на самом навороченном из доступных средств? Для чистоты эксперимента предположим что у вас идеальные условия -- время не давит, начальство всем довольно, заказчики с кровавыми топорами к двери кабинета не подкрадываются. Лично я встречал людей, которые эффективно пишут хороший код и по первому и по второму принципам. И я видел откровенно никчёмный код написанный и так и так.
0) Сначала задача решается на РУССКОМ языке.
1) Потом ищется средство (опенсоурсное), которое что-то похожее уже делает. Ведь "все написано до нас".
2) Если п1 не работает, то пишется на С++. Кхм... Без ООП
Прочитал. Адская смесь. T>...
Понял так.
Первый принцип это: "написать просто и эффективно"
Второй принцип: "написать быстро с большим оверхедом на самом навороченном из доступных средств"
T>Но в защиту первого принципа у меня есть очень как мне кажется веский аргумент и имя ему -- повторное использование.
Ээээ.... Не понял
T>Ещё хуже -- *иллюзия* возможности реюза, которую дают классы. Вы наследуетесь от кого-то...
"реюз" (повторное использование) и наследование вещи ортогональные
T>...
Дальше идёт на мой взгляд плохо структурированный поток мнений/высказываний
Здравствуйте, Tilir, Вы писали:
T>Представьте, что перед вами стоит задача. Вы сначала попытаетесь воплотить её на самом простом и эффективном из доступных вам средств/языков (грубо говоря: написать на C, хотя и не обязательно, я сейчас не о конкретных языках а о принципе) и только если станет ясно, что запутываетесь и реально нужны более сложные средства (скажем очевидно, что ООП сильно помогло бы или вообще без сборки мусора явно плохо), примените их или наоборот сначала быстро решите её пусть даже с большим оверхедом на самом навороченном из доступных средств?
Если передо мной стоит задача, я ее прежде всего осмысливаю. Изучаю предметную область, бизнес-контекст, роюсь в Гугле, приношу жертвы и вопрошаю оракулов. В результате анализа получаются набор сущностей и их взаимодействий. Иногда специфика получившейся модели подсказывает, на чем лучше делать реализацию. Обычно язык задан заранее, поскольку в масштабной промышленной разработке изолированные задачи встречаются немногим чаще, чем сферические кони в вакууме.
Как правило, "навороченные средства" позволяют решить задачу быстрее, поскольку их авторы уже потратили кучу сил и времени на реализацию того, что мне придется делать самому при разработке на "низком уровне". Если, скажем, я занимаюсь CAD системой, то мой работодатель не готов платить мне за написание собственной версии malloc (пока я не объясню ему, сколько дополнительной прибыли это принесет)
T>Для чистоты эксперимента предположим что у вас идеальные условия -- время не давит, начальство всем довольно, заказчики с кровавыми топорами к двери кабинета не подкрадываются.
Разработкой ПО я зарабатываю на жизнь. В промышленной разработке время -- самый дефицитный ресурс. Поэтому любую задачу я постараюсь решить самым быстрым путем. Разумеется, с учетом ограничений на коммерческую доступность используемых компонент, необходимости поддержки в будущем, надежность, производительность и т.д. и т.п.