Комментарии 101
И чем опытнее тот, кто проектирует, тем лучше он может предугадать вероятность Z.
Profit = M(z)*P(z) — (M(X) — M(Y)), где
Y — максимально дешёвое, из всех подходящих решений. Назовём его стандартным подходом.
z — потенциальная проблема, которая может возникнуть в будущем. (намерено написана маленькой, что бы подчеркнуть различие: X, Y — суть решения, в то время как z — проблема)
X — более дорогое решение, которое представляет собой объединение стандартного подхода Y и решения проблемы z.
M(X) и M(Y) — стоимость реализации решений X и Y, соответственно.
M(z) — потенциальный убыток, в случае наступления z.
P(z) — вероятность наступления z.
Profit — потенциальная прибыль от использования более дорогого подхода X, вместо стандартного Y.
Очевидно, что:
- Если Profit сильно больше 0, то нужно использовать более дорогое решение, даже если вероятность возникновения проблемы крайне мала.
- При этом, если Profit сильно отрицателен, то подход X использовать никак нельзя, даже если наступление проблемы z почти гарантированно и убытки от него велики. Такое может произойти, например, в случае, если X несоизмеримо дороже Y.
- Если же Profit мало отличается от 0, то можно использовать что угодно.
Это была шутка, на самом деле такого я никому не пожелаю.
Мне интересно, как так получилось, что 99% кода — запас?) А где функционал то?)
Надо просто погуглить и использование нужной технологии сразу упростит «вариант Z через 5 лет».
Самый цимес, что переписать это вот всё на технологии «сегодня плюс пять лет» через пять лет окажется дороже, чем впихнуть в эти технологии будущего простое как табуретка решение Y.
хотя здравая мысль всё же в этом есть. Главное не возводить её в абсолют.
Например, вот дешёвый большой сервер:
[...]
Такой сервер стоит от ~800 до $1300 в месяц в зависимости от местоположения. Вы можете взять десяток за зарплату опытного инженера DevOps в Лондоне.
Лихо.
Могу поспорить, что у большинство распределённого программного обеспечения требует рабочую нагрузку менее чем в половину от мощности этого любительского сервера.
В обычное время работает — и ладно, а на пики как-то поровну? Железо нынче дешёвое, но вот простои бизнеса по-прежнему очень дороги.
Впрочем, особенно в стартапе если не закладываться на рост 1000% в год, можно быстро обанкротиться.
Слишком безаппеляционное заявление. Наш проект переделывался «серьёзно» 0 раз, работает больше 10 лет, популярность только растёт, представляет из себя упомянутую ниже «веб-службу» :)
А можно хотя бы один правильный пример?
Для инфраструктуры нужны Kubernetes и Docker, хотя один большой сервер гораздо проще, но когда придётся масштабироваться до 11-ти серверов, это упростит нам жизнь.
Автор, а вы жили с одним большим сервером, на котором все крутится? Попробуйте, и вы больше никогда в жизни не будете предлагать такой вариант. Не обязательно прямо docker и kubernetes, но хотя бы виртуалки у вас там точно будут.
Для обработки данных нужен распределённый дизайн, хотя централизованное решение гораздо проще, но когда клиент потребует 99,999% безотказной работы в SLA, это упростит нам жизнь.
В противном случае, когда клиент захочет какой либо HA, в 9 из 10 случаев вся инфраструктура покроется костылями со всех сторон, что бы сделать приложение, которое рассчитывает, что оно одно такое распределенным.
Нужно набрать команду разработчиков и создать собственное программное обеспечение, хотя Wordpress и Shopify гораздо проще, но когда клиентская база вырастет в 100 раз, это упростит нам жизнь.
А почему именно клиентская база в 100 раз? Тут стоит исходить из вопросов доработок, как мне кажется, и далеко не всегда получается так, что написать с нуля плохая идея.
Нужно использовать дизайн на основе наследования типов, хотя композиция гораздо проще, но после 5 лет увеличения кодовой базы это упростит нам жизнь.
Эм… что? В каком месте композиция заменяет наследования?
Нужно написать код в C++ с кэшированием представлений, хотя Python-скрипт с прямыми запросами к Postgres гораздо проще, но при большом увеличении объёма данных это упростит нам жизнь.
Эм… а что мешает просто написать скрипт на python через celery, что бы он масштабировался?
Автор, а вы жили с одним большим сервером, на котором все крутится? Попробуйте, и вы больше никогда в жизни не будете предлагать такой вариант. Не обязательно прямо docker и kubernetes, но хотя бы виртуалки у вас там точно будут.
Мне почему-то кажется, что ситуация "по виртуалке на продукт" автора более чем устроит. Более того, такой вариант позволит даже немного вертикально масштабироваться путем переноса виртуалок на новые сервера.
Ну, тогда уж по виртуалке на приложение, но проблема в том, что такая схема слишком избыточна, когда у вас много мелких приложений. Менеджить 1000 и 1 сервер все-таки не очень круто.
Вот тут из ниоткуда и приходит более удобная схема виртуалка на смысловую единицу и в ней несколько docker контейнеров для приложений. Ну а потом захочется отказаться от смысловых единиц и получится kubernetes/nomad.
Желаю удачи автору с таким подходом. В России все сложнее, ибо что со стартапом, что со средней руки конторой реальные обстоятельства вносят свои коррективы в виде "Вот тебе списанный P4 2.8/1.5gb DDR1/80gb hdd, сделай на базе этого сервер для 10000 клиентов, чтоб летал 24/7/365 и с перспективой на будущее. Ах, да, ещё блокчейн делай. Не знаю, что это такое, но звучит круто". Это, кстати, реальный пример. В самом лучшем случае ещё можно "выбить" что-то типа 2x Xeon X5460/8gb DDR2-800/2x240gb.
А тут нам буржуи ещё заливают про бесполезность избыточной оптимизации, отсутствие перспектив на будущее и т.д.
Хохма в том, что на этом вашем списанном P4 2.8/1.5gb DDR1/80gb hdd вы нормальный Kubernetes тоже не поднимете. Ну, его самого может и поднимете, но вот для нужного количества микросервисов ресурсов уже не найдется. А вот монолитное приложение может даже суметь заработать — все же у монолита куда меньше накладные расходы.
Докинуть 2 плашки по 512 из личных запасов(итого 2.5 гб) — и со скрипом самописная распределялка заводилась(Kubernetes, само собой, не потянет, но вот "комплекс распределенных БД" 2006 года(самописная вариация на тему SQL из позапрошлого места работы коллеги) позволил успешно раскидать все задачи сначала на 1, а потом и на 4 таких пылесоса, нормальные контейнеры колхозили уже сильно после нас на списанном 771 ксеоне от центрального филиала, когда задержки имеющейся конструкции начали переходить за 8 секунд).
P.S. На почти таком же "четвертьпне", но в разгоне до 3.5 и с 4 гигами DDR2 "кубы" заводились и работали(отладочный стенд перед продакшеном).
Статья очень правильная. Хватит уже писать универсальные овер инженерные программы, фантазируя о будущем. Понятный код, который специально заточен под бизнес сценарий в сто раз проще и дешевле переписать, чем мега дизайн с тонной абстракций, который делали в надежде на светлое будущее которое никогда не наступит. Решайте текущую задачу без далёких фантазий о будущем. Время потраченное на универсальность сейчас, отнимает время от действительно нужных бизнесу задач.
Понятный код, который специально заточен под бизнес сценарий в сто раз проще и дешевле переписать
На самом деле, нет. Или у вас просто нет абстракций.
О вот и любители писать в далекий завтрашний день подоспели, громкими заявлениями.
Абстракции не возникают на пустом месте, они вырождаются при поступлении новых use case'ов с учётом уже реализованых текущих.
Могу привести простой пример. Нечто пишется в файл, простое. Для чего делать абстракцию и растрачивать сложность, если file.wriebytes или file.writetext решает все проблемы. Требований нет — выдумывать не надо.
Как появится новое требование надо читать писать из файла и по сети, вот, тогда уже надо подумать над дизайном. Потом появится ещё посередине кеш, опять придется чуть чуть переделать, но главное не делать это заранее, потому что время будет потрачено, КПД абстракций близко к нулю, т.к. простой метод решает задачу.
Это все круто и понятно выглядит на простых примерах.
А когда вы написали функцию, которая пишет в файл, потом переиспользовали ее в куче мест в проекте, а потом вам надо изменить ее поведение так, что бы она работала по другому — вы ломаете половину проекта, потому что вы завязаны на конкретную реализацию вместо абстракции, которая гарантирует только результат, а не то, как оно будет работать внутри функции.
Если это используется в куче мест, то SomeUtil.ReadFromFile
Семантику вызова хранит функция. Переделка стоит 2копейки. Но если ради этого сделают пару интерфейсов и несколько классов — классический оверинжениринг.
SoneUtils должны называеться по области названия этих данных.
Все просто: мы знаем где это используется, и легко можно оценить масштаб переделки. Но такой подход сложен при разработке фреймворка.
Один из тысячи проектов взлетает до больших нагрузок. Зато при мне пара умерла, в стадии «4 пользователя в день, но мы прикручиваем Редис для пользовательских сессий».
bash.im/quote/420672
Вася и Петя одновременно начали писать один и тот же продукт.
Вася был «ориентирован на результат» и начал сразу писать говнокод не продумав толком архитектуру.
А Петя месяц разрабатывал архитектуру, месяц делал удобный интуитивный интерфейс, которому позавидывал бы Джони Айв, потом месяц писал тесты, потом два месяца писал сам код и получил идеальное стабильное приложение.
Но Вася выпустил уже через месяц первую версию программы, пусть и не идеальную, пусть с багами, но рабочую, и начал её продавать. Ещё через месяц выпустил вторую версию исправляющие баги первой и добавляющие новые баги. Ещё через месяц на доходы от продаж нанял двух толковых программеров, которые за два месяца перелопатили весь код, согласно пожеланиям пользователей допилили интерфейс и выпустили третью версию программы.
Итого, через пять месяцев у Васи было два работника, куча клиентов и сносно работающее приложение отвечающее желаниям клиентов.
У Пети было вылизанное никому не известное приложение, минус на банковском счёте и ни одного клиента.
В завершение этого выдуманного примера можно сказать, что через полгода Вася купил все наработки Пети, Петю взял в штат тестировщиком, а сам по пьяни разбился на своём новеньком Туареге
Но надо предусмотреть возможность расширения приложения, библиотеки…
Думаю для этого и есть принципы, подходы такие как GRASP, SOLID, REP, CCP, CRP…
Ну и после таких статей приходят в сотрудники девы, которые шлют по паре запросов в базу на каждый кейпресс в поле поиска, а потом удивляются, что ж всё так тормозит когда приложением пользуется хотя бы сотня-другая пользователей, а данных чуть поболее, чем тестовый набор.
Про то, что производительность железа постоянно растёт линейно и будет так расти до конца двадцатых годов я тоже что-то не вижу.
Оверинжиниринг — бесспорно плохо, но думать хотя бы на обозримое будущее и планировать какую-то нагрузку и базу пользователей хотя бы на год вперёд всё же стоит.
Проекту более 10 лет. Был сделан как советует автор — только то, что надо, без всяких запасов. Проект постоянно дорабатывался по требованиям заказчика. Если сравнить, что было на старте и что сейчас, то это два разных проекта. Доработки на базе первоначальной архитектуры и логики стоят давно уже не дешево. И возможно, что если бы заказчик на старте лучше подумал о перспективах и больше потратил на это своего времени, то проект в сумме обошелся бы ему дешевле.
Так же и программист часто поступает, когда берется за разработку, начинает метаться вокруг старых проблем предыдущих проектов, которые пытается решить с ходу, не задумываясь будут ли эти проблемы.
По этому и цены такие подходы как Agile, что бы проверить теорию на практике, чем раньше, тем лучше.
Такие подходы как Бережливая разработка(то есть не спешить с выводами и не городить безумие) спасают от лишних затрат как денег, так и времени.
Проекту более 10 лет.
И возможно, что если бы заказчик на старте лучше подумал о перспективах и больше потратил на это своего времени, то проект в сумме обошелся бы ему дешевле.
Возможно, если бы заказчик так сделал, то проект бы загнулся через год.
Автор «колхозник», который, взяв правильную идею что over-engineering это плохо, превратил её в идиотскую схему «купите один мощный сервер, так проще разрабатывать». Рискну предположить, что такое решение может быть основой только такого бизнеса, которому вообще не нужен сервер, всё можно решить наймом людей и покупкой G Suite для совместной работы.
если серьезно, сейчас железо стоит дешевле чем часы разработчика. И да, иногда проще купить железа побольше и наваять нужный функционал, да не оптимизированный, но быстро разработанный и быстрее понять нужно это или нет, и понять куда двигаться, чем вбухать 2 годовых бюджета и получить полный провал… бизнес, он такой бизнес
иногда. О том и речь. Иногда так, иногда иначе. Нельзя так категорично.
Автор не категоричен, он просто пишет о том, куда уходят деньги и время…
Сам по юности ваял сверх прочную систему(за свой счет и время), теперь понял что это порыв, вызов для программиста, но время и опыт показал что нужно себя держать в руках и видеть чуть больше, заходить за рамки профессии.
Можно мне сервер, который никогда не ломается, который находится в датацентре, в котором никогда не бывает аварий со 100% связностью с, хотя бы, всей Россией?
Никто не просит экономить такты процессорного времени, люди вон JS-ом воздух греют в датацентрах, просто есть проблемы, которые деньгами решаются не в пропорции 2, а в пропорции 100 например. И на такие расходы очень редко кто может пойти.
Вы вообще не поняли о чём я писал, вероятно в силу моего неумелого изложения. Купить сервер потолще не проблема, а давать людям совет «не делайте распределённых систем» это проблема. Это ужасный совет, который ведёт к колоссальным расходам на обеспечение функционирования бизнеса, невозможности улучшения ситуации и деградации разработчиков.
Пусть они хоть на Коболе пишут, но никакой сервис проектировать на работу на одной машине нельзя. Исключения есть, потом про них пишут статьи тут, «как мы купили второй в мире супершкаф, который никогда не ломается за столько денег что и сказать не сможем, потому что наша система не подлежит распределению», буквально недавно тут была такая статья.
Я постараюсь объяснить свою точку зрения...
Вы вообще не поняли о чём я писал, вероятно в силу моего неумелого изложения.
Купить сервер потолще не проблема, а давать людям совет «не делайте распределённых систем» это проблема.
Не надо тех.специалистам давать советы(как сделать) именно сверху, менеджмента, или руководства, специалисты на то и специалисты что знают как решить +100500 проблем, но и специалистам надо задуматься и больше общаться с любым видом заказчиков функционала которые могут не понимать технической части и решать именно нужные проблемы, но и специалисты должны вовремя предупредить заказчика о возможных рисках..
А то полгода конструируешь подводную лодку, а потом только понимаешь, что нужен-то был самолет. Зато микросервисы есть, и кластер с файловером.
Например: Чем создание за три месяца трех прототипов подлодок и выбрасывание их на помойку поможет клиенту если ему нужен самолет?
Ничем. Но обычно предполагается, что увидев первую из подлодок клиент воскликнет: да мне же самолет нужен, а не подлодка! :-)
Ну а если бюджет сожрал даже первый прототип — то у проекта вовсе шансов не было ни при каких раскладах.
Ну ему подлодку и сделали. А потом вдруг выясняется, что там в море уже все противолодочными сетями заставленно (Заказчик про это и САМ НЕ ЗНАЛ). И только самолет.
Смысл не в том, что программисты не слушают заказчика, а в том, что заказчик не знает, чего он хочет. Это аксиома современности.
Есть методология разработки, называется «водопад». Это когда вначале хорошенько думают, анализируют, пишут требования и тз, а потом по нему реализовывают и отдают готовый продукт. Это хорошо для создания спутников и строительства зданий, когда требования заранее известны и меняться не будут ни сейчас, ни через год.
Но для стартапов «сделать по ТЗ» — это смерть. Наверное, процентов так 95 современных айтишных проектов — это попытка попасть пальцем в небо. Есть лишь смутные идеи, предположения о том, что должно «выстрелить», и цель в данном случае — не реализовать идею, а протестировать её в реальном мире. Каждый месяц, если не каждую неделю, что-то изменяется, одни фичи вдруг становятся не нужны, а вместо них появляются новые. Сделать правильно сразу в таком случае никак не получится. А вот когда что-то «нащупали», тогда да, можно наконец написать правильно.
Барри Боэм построил первую версию того, что Стив Макконелл позднее назвал «конкурс неопределенности», конкурс неопределенности говорит о том, что на этапе оценки осущетвимости проекта оцена обычно отклоняется от истины на 60-160%. Иначе говоря, проект, который, как кажется, должен занять 20 недель, может потребоваться от 12 до 32 недель. После формулирования требований в письменом виде оценка может отклоняться на ± 15% в любом направлении, т.е. плановый срок 20 недель может сократиться до 17 недель или вырасти до 23 недель
Институт управления проектами имеет сходную точку зрения… ИУП предлагает принимать начальный уровень отклонения оценки в диапозоне от +75% до -25%
также есть статистика что часто 64% функционала приложения не используется конечными пользователями.
от сюда и появились такие вещи как MVP, методология Спринт от гугла…
В продолжение вашего примера с банком, все как вы и говорите.
Сам опыта разработки ПО для банков не имею.
Но есть другой простой пример. Разрабатывал систему биллинга, да часть вещей можно уложить в точное Т.З., но многое, особенно интерфейс для работы, переделывали 3 раза, и только после 3 раза получилось сделать удобное приложение, по этому изначально и не пытались обдумать все и особо запаса не делали.
и только после 3 раза получилось сделать удобное приложение, по этому изначально и не пытались обдумать
Ну так проблема была как раз не в том, что есть большая сложность изначально спроектировать биллинг удобным и обойтись без переделок ТЗ на ходу. А в том, что не пытались.
Есть софт уникальный, новаторский. Есть софт типовой. Этих биллингов уже написано тысячи, «best practices» все давно известны, все потребности клиентов и как их лучше оформить в UI, всё это тоже пройдено вдоль и поперёк. И то, что заказчик вместе с разработчиком вместо «взять как у других и сделать так же», несколько раз переделывал, это как раз всего лишь отсутствие компетенции. Намного дешевле было бы взять кого-то в команду, кто эти биллинги видел в лицо :)
Для UI были сделаны прототипы, которые пробовали конечные пользователи. Но во время работы находились тонкости, конечно с каждым разом переделывали, добавляли и изменяли меньше. Но именно уже на практическом использовании ПО было понятно какие проблемы не учли, что можно еще добавить и т.д.
Есть еще одно наблюдение, независимое от «серьезности» проекта. Оно касается дизайна. Очень часто бывает так: обсудили фичи, обдумали интерфейс, дизайнер нарисовал. Вроде все круто, красиво, соответствует требованиям. А потом верстальщик отверстал, программист закодил, начали пользоваться и поняли, что неудобно. Как-то так получается, что теоретически все ок, а на практике вылезает то, о чем не подумал ни заказчик, ни разработчик. А значит, нужно построить процесс таким образом, чтобы уже на ранней стадии разработки можно было не просто посмотреть на картинки, но и вручную поиграться — понажимать на кнопки, поотправлять формы и тд. Еще даже до того, как начать писать бекенд. А это уже и есть прототип.
А самые продвинутые сразу верстают разные варианты и потом тестируют их всей толпой, не доверяя заказчику — потому что мнение об удобстве интерфейса от пары десятков человек объективнее мнения одного человека.
Вот снова ваш пример из веб разработки. Других нет в этом мире?Я стараюсь не спорить с людьми в тех областях, где я некомпетентен. Допускаю, что есть множество дел, где нужно делать качественно и «в продакшен» уже на первой итерации. Но сам с таким не сталкивался.
Но что мешало продумать хотя бы на 1 шаг в перед и сделать структуру сразу такой? Трудозатраты суммарные были меньше на порядок и срок исполнения тоже не был бы выше.А это уже и есть мастерство. Но оно не в том, чтобы всегда делать «на один шаг вперед», а в том, чтобы понимать, когда стоит остановиться. Мы, программисты, народ увлеченный — под настроение можем вместо одного конкретного велосипеда сконструировать завод по производству средств передвижения — от самокатов до самолетов, потому что «ну мало ли, а вдруг пригодится».
Хватит разрабатывать софт с запасом