Comments 18
Вы попросили вполне конкретный, узкоспециализированный продукт с парой нужных вам дополнительных фич. Команда разработки услышала это иначе.
Потому что командна разработчиков научена тому, что если реально сделать узкоспециализированный продукт без возможностей расширения — то все, дальше дело труба?
Вот проиндексировать весь Интернет, а после этого выдавать релевантные поисковые результаты за долю секунды — вот это сложно. Однако пара ребят в гараже это сделала.
Это там, где сначала был поиск слов? Нет, это не сложно. Современные алгоритмы google — вот что сложно, но пара парней в гараже их не писала.
Самая большая проблема в том, что очень сложно найти баланс между расширением и сложность архитектуры и производительностью. Ну и всякие процесные проблемы, но они не то, что бы сложные, просто они есть.
сложно найти баланс между расширением и сложность архитектуры и производительностью
Нет — это не так сложно. Есть простые принципы KISS, DRY и YAGNI
Чем проще написан код, тем проще его расширять и поддерживать. Многие программисты страдают от «универсальности». К примеру пришла задача обработать данные по протоколу (К примеру команды по MODBUS или CAN) Некоторые разработчики начинают задавать себе вопрос, а что если завтра нужно будет добавить ещё один протокол или изменить получателя… В результате вместо простой связки интерфейса и класса рождается монстр, близкий по функционалу к BizTalk с возможностью изменения протоколов в конфигурации. Только часто бывает, что день, когда вас попросят добавить 2ой протокол так и не наступит, а вам придётся поддерживать и исправлять ошибки в десятках тысяч строк ненужного кода (а ведь могло быть всего пара сотен строк...) Если бы у меня была такая задача, то я бы сделал интерфейс (для возможной расширяемости в будущем) и его реализацию в виде класса, который делает только то что нужно для данного протокола. Закинул бы его через DI или ServiceLocator и всё…
Когда вам сказали, что абстрактный принцип, сформулированный в качестве красивой аббревиатуры может быть простым — вас обманули. Иначе можно было бы просто следовать принципу ППП (Просто пиши правильно) и не парится.
Что бы не быть голосновным:
KISS — довольно абстрактный принцип, который можно еще записать "не усложняйте сверх меры", но опять же, проблема в том, что бы найти эту меру, а это не тривиальная задача.
DRY — принцип, который можно рассматривать очень по разному. Некоторые программисты считают строчки кода, которые повторяются и если их больше трех, сразу начинают обобщать. Некоторые более опытные описывают DRY в связке с SRP, и говорят, что если для одного изменения для одного актора в программе нужно менять код в двух местах — вот тут проблема в DRY может быть.
YAGNI — Не очень популярный принцип опять же, потому что никогда не понятно, когда на самом деле нужно, а когда нет. Я не знаю бывало ли у вас такое, но я бывал в ситуациях, когда абстракции или какого-то усложнения сверху не было, а изменения понадобились. И все было очень плохо.
Касательно вашего примера, как я понимаю, вместо разделения на абстрактный класс и реализацию просто сделали реализацию в одном классе? Грустно, но это базовые ошибки проектирования, мне кажется, вот тут точно проблем не должно быть.
Для себя выработал следующие правила
KISS — Поставленная задача должна решаться самым простым из возможных способов. Код должен быть легко-читаемым, легко-модифицируемым и расширяемым, но должно быть реализовано только то, что нужно на данный момент.
DRY — Изменения должны происходить в минимальном количестве мест (не всегда получается сделать что только в одном). При внесении изменений не должен меняться одинаковый код (например поиском и заменой по коду).
YAGNI — Не пиши лишний код и удаляй ненужный (если он есть в системе контроля версий конечно).
По поводу необходимости изменения кода там, где нет абстракций — значит пришло время их добавить… (Что соответствует данным принципам). Если код написан по KISS и DRY — добавление абстракции произойдёт в одном месте и затронет минимальное количество кода.
KISS — Поставленная задача должна решаться самым простым из возможных способов. Код должен быть легко-читаемым, легко-модифицируемым и расширяемым, но должно быть реализовано только то, что нужно на данный момент.
У вас всего лишь три параметра, которые довольно часто обратнозависимы, а так, разумеется, все просто.
DRY — Изменения должны происходить в минимальном количестве мест (не всегда получается сделать что только в одном). При внесении изменений не должен меняться одинаковый код (например поиском и заменой по коду).
Как я уже писал выше "поиск по коду" — это не совсем правильный подход. В таком подходе вы упускаете моменты, когда код выглядит одинаково, но вызывается из разных мест и так и должно быть.
YAGNI — Не пиши лишний код и удаляй ненужный (если он есть в системе контроля версий конечно).
Класс. А какой код нужный и какой код ненужный?
По поводу необходимости изменения кода там, где нет абстракций — значит пришло время их добавить
Вы когда-то такое делали? Ну, не в домашнем своем проекте, а в реальном, где куча людей, параллельно разрабатывают какие-то фичи, а еще нифига нет тестов и прочее?
У вас всего лишь три параметра, которые довольно часто обратнозависимыЧаще всего там нет обратной зависимости. Чем меньше кода написано, тем проще его понимать, расширять и модифицировать. (Это конечно не значит, что всё нужно писать в Code-Behind onclick)
код выглядит одинаково, но вызывается из разных мест— Это как раз признак того, что код написан по DRY — вызовов много, а вызываемый код — общий. Конечно, если нужно поменять сами вызовы, то без поиска и замены не обойтись, но предполагается что весь код написан по DRY — т.е. количество вызовов максимально сокращено…
А какой код нужный и какой код ненужный?Ненужный в данном случае — неиспользуемый/мёртвый или закомментированный.
Вы когда-то такое делали? Ну, не в домашнем своем проекте, а в реальном, где куча людей, параллельно разрабатывают какие-то фичи, а еще нифига нет тестов и прочее?
Конечно делал! Но соблюдение этих принципов не значит «забивание» на архитектуру приложения. Если код вызывается в куче мест, то он должен быть написан так, чтобы его можно было модифицировать (но если этого не предусмотрели изначально — значит нужно добавить) — всё-же пройтись по десяткам методов и заменить класс на интерфейс сделать проще, чем разбираться с кучей ненужных абстракций, зависимостей и конфигураций
Иначе можно было бы просто следовать принципу ППП (Просто пиши правильно) и не парится.
На самом деле, все очень просто — принципы фиксируют стандартное поведение. Стандартное поведение — это такое, которому стоит следовать, если не получается четко и ясно сформулировать причины, по которым ему следовать не надо.
KISS — не надо делать систему сложнее, если вы не можете объяснить, почему она должна быть сложнее
DRY — стоит избегать дублирования во всех случаях, в которых вы не можете объяснить, почему дублирование необходимо
YAGNI — не стоит добавлять функциональность, если вы не можете аргументировано пояснить, почему ее следует добавить прямо сейчас
А для отката транзакции нужно 1000 человек и полгода.
Вот это очень плохой пример.
Откат транзакции в банке N если что технически не сложен. Но вот пока все банки участвующие в цепочки договорятся о том как будет проходить откат итд, может пройти лет 5.
Основная проблема в законах.
Красное сторно не такая и простая штука. Причем требующая так же особые документы.
Реверс идет уже за вычетом комиссии, итд. + не все банки партнёры работающие с банком N согласятся его делать просто так.
В общем ваш пример полный шлак. Не знаете как оно работает, лучше не пишите. Мне же довелось в написании примерно такого же участвовать.
А вот про единую банковскую платформу — это конечно интересно, но скорее всего невозможно из-за разных процессов в каждом банке (которые они чтят и берегут как традиции), да и сейчас преимущество в софте — это почти единственная разница между банками. Так что единую систему мы ещё очень не скоро увидим…
Мне вот по опыту чаще приходилось встречаться с софтом, который писался как «простой инструмент для решения одной маленькой частной задачи». А когда задача расширилась — превратился в зверя с обложки книги про perl 6.
А когда придумали слово Agile, написание софта таким способом стало модным.
Я конечно не агитирую за возврат к водопадной модели, но даже с аджайлом можно уделять больше внимания проектированию и архитектуре.
Надо простую задачу пдавать как вызов для разработчиков: ааот сделайте это просто и надежно...
Что реально сложно (или невозможно) — предусмотреть все возможные точки расширения функционала.
Воображаемые проблемы — корень плохого ПО