День 1857. #Холивар
Возник у нас тут небольшой спор с Кириллом, автором канала C# Heppard (кстати, подписывайтесь). Кирилл пишет:
И ещё несколько лет назад, я бы тоже посмеялся над мужиком. А тут… В общем, не знаю почему, но решил я выступить адвокатом дьявола)))
Тут надо оговориться, что Кирилл в основном занимается оптимизациями, а я всё-таки фуллстек, и экономия байтиков и наносекунд для меня скорей теоретическая область и «чисто по фану». То есть, я практически этим не занимаюсь, т.к. в моей практике я чаще оптимизирую запросы к БД или UI в браузере. Но…
В принципе, мужик не так уж и не прав. Понятно, что нет серебряной пули, и у всех ситуации разные. Но, как мне кажется, в довольно приличном количестве случаев апгрейд железа – действительно выход. Понятно, что мы - программисты, мы все любим чистый и быстрый код. Хлебом нас не корми, дай реализовать свой супербыстрый и эффективный по памяти вариант сортировки или словаря.
Но давайте перенесёмся на самый высокий уровень – уровень бизнеса. Как говорит Марк Симан: «Не забывайте, что в конечном итоге, вы делаете продукт, который должен решать задачи бизнеса». Так вот, с точки зрения бизнеса, оптимизировать алгоритм или докупить памяти – разницы нет. Всё выражается в деньгах. Надо заплатить за одно или за другое. Если ПМ, техлид или другой менеджер этого уровня прикинет, как говорится, писю к носу, и сравнит, сколько денег будет стоить апгрейд железа, и сколько примерно надо потратить человекочасов (умноженных на часовую ставку программистов) на оптимизацию, то вполне может оказаться, что «докупить плашку памяти» просто выгоднее для бизнеса (по крайней мере, на ближайшую перспективу).
Конечно, тут будет множество нюансов, особенно если дело касается облачных решений. Там просто так памяти не докинешь, это будут размазанные по времени постоянные издержки, и конечно, через какое-то время оптимизация окажется дешевле. А если мы говорим о микросервисах, кубернетисах и вот этом вот всём, то там ограничения на железо ещё более строгие.
В общем, давайте обсудим. Что думаете? Апгрейд железа может быть опцией? Бывали ли у вас в практике такие случаи?
Возник у нас тут небольшой спор с Кириллом, автором канала C# Heppard (кстати, подписывайтесь). Кирилл пишет:
«Я всегда вспоминаю один диалог. Состоялся он, ох, уж сколько лет прошло, на одном локальном митапе. Я, как всегда, вещал про то, что было бы неплохо писать оптимальный код, в том смысле, чтобы экономить байтики и наносекунды. То да сё, слайды, смешки, лёгкое непонимание в глазах слушателей. Наконец, секция вопросов и ответов.
Я хорошо помню этого мужика, который во время доклада делал фейс-палмы, громко ёрзал стулом, сидел в телефоне. Я ждал вопросов от него и дождался.
- Скажите, а зачем всё это?
- В смысле, - не понимаю я.
- В том смысле, - сказал он авторитетно, - что это всё не нужно. Проще купить плашку в 16 ГБ памяти, чем всё это знать.»
И ещё несколько лет назад, я бы тоже посмеялся над мужиком. А тут… В общем, не знаю почему, но решил я выступить адвокатом дьявола)))
Тут надо оговориться, что Кирилл в основном занимается оптимизациями, а я всё-таки фуллстек, и экономия байтиков и наносекунд для меня скорей теоретическая область и «чисто по фану». То есть, я практически этим не занимаюсь, т.к. в моей практике я чаще оптимизирую запросы к БД или UI в браузере. Но…
В принципе, мужик не так уж и не прав. Понятно, что нет серебряной пули, и у всех ситуации разные. Но, как мне кажется, в довольно приличном количестве случаев апгрейд железа – действительно выход. Понятно, что мы - программисты, мы все любим чистый и быстрый код. Хлебом нас не корми, дай реализовать свой супербыстрый и эффективный по памяти вариант сортировки или словаря.
Но давайте перенесёмся на самый высокий уровень – уровень бизнеса. Как говорит Марк Симан: «Не забывайте, что в конечном итоге, вы делаете продукт, который должен решать задачи бизнеса». Так вот, с точки зрения бизнеса, оптимизировать алгоритм или докупить памяти – разницы нет. Всё выражается в деньгах. Надо заплатить за одно или за другое. Если ПМ, техлид или другой менеджер этого уровня прикинет, как говорится, писю к носу, и сравнит, сколько денег будет стоить апгрейд железа, и сколько примерно надо потратить человекочасов (умноженных на часовую ставку программистов) на оптимизацию, то вполне может оказаться, что «докупить плашку памяти» просто выгоднее для бизнеса (по крайней мере, на ближайшую перспективу).
Конечно, тут будет множество нюансов, особенно если дело касается облачных решений. Там просто так памяти не докинешь, это будут размазанные по времени постоянные издержки, и конечно, через какое-то время оптимизация окажется дешевле. А если мы говорим о микросервисах, кубернетисах и вот этом вот всём, то там ограничения на железо ещё более строгие.
В общем, давайте обсудим. Что думаете? Апгрейд железа может быть опцией? Бывали ли у вас в практике такие случаи?
👍39
Техника работодателя и работа на ней... #холивар
(С)тянуто из соседнего чатика, надеюсь, там поймут и простят.
(С)тянуто из соседнего чатика, надеюсь, там поймут и простят.
Anonymous Poll
32%
Работодатель обязан предоставить хорошую технику в любом случае
23%
Работодатель обязан предоставить технику хотя бы в офисе (на удалёнке, так и быть, буду на своей)
12%
Если работодатель даст, могу работать на ней, если нет, буду на своей
27%
Если работодатель требует уснавку ВПН, и прочих трекеров, пусть даёт технику
5%
То, что предлагают работодатели, меня не устраивает, работаю только на своей технике
1%
Свой вариант (напишу в комментариях)
День 2126. #Холивар
Композиция или наследование
Возникли у нас как-то с коллегой разногласия по поводу реализации одной функциональности. Лучшие практики объектно-ориентированного проектирования советуют нам предпочитать композицию наследованию. Но всегда ли это верно?
Коротко о домене. Есть у нас сервис поиска поставщиков электронных деталей, и сайт, на котором его можно осуществлять по подписке. А ещё есть сервис, который мы предоставляем производителям этих деталей. Заключается он в том, что мы даём им доступ к результатам нашего поиска «на их сайте». Чтобы на их сайте покупатель мог легко найти, какие поставщики их деталей есть рядом. Да, в наше время уже 99,9% читателей подумали бы, что мы предоставляем API, но нет. В смысле, API тоже есть, но поскольку сервису уже почти 20 лет и не у каждого производителя есть отдел разработки, который мог бы прикрутить этот API к их сайту, есть у нас и другая опция. Мы создаём страницы с функциональностью (поиск, результаты, возможность заказа и т.п.) и подгоняем их под внешний вид сайта производителя.
К сути. Конечно, каждый наш клиент хочет, чтобы функциональность максимально соответствовала его сайту. И стандартная реализация не всегда подходит. Кто-то хочет разную логику поиска: «с начала», «содержит», «равно». Кто-то разные регионы: по умолчанию результаты делятся на Америка, Европа и Азия, но некоторые просят поделить по-другому. И так далее, там настроек выше крыши. Большинство из них легко сохраняется в JSON, но не все. Например, кто-то хочет, чтоб на странице результатов поиска повторялась форма поиска, а кто-то, чтоб результаты определённого поставщика показывались сверху. Тут уже не избежать кастомной бизнес-логики.
Мы сошлись на том, что должен быть базовый класс со стандартным поведением, реализующий интерфейс. Вот его упрощённый код. Только методы, каждый из которых реализует нужный кусок функциональности (допустим, форматирует вывод):
Кроме того, мы сошлись на том, что в случае, когда нужно что-то поменять, мы просто создаём отдельный класс для определённого производителя и переопределяем там нужную логику. Потом в DI-контейнере для каждого производителя внедряется либо класс по умолчанию, либо его специализированный (если он есть).
Так вот, моя реализация предполагала, что спец-класс просто наследовал бы от базового и переопределял нужную функциональность:
Остальные методы автоматически наследовались бы. Коллега настаивал на предпочтении композиции наследованию, и что мы должны делать декоратор базового класса. Как-то так:
По мне так в декораторе куча лишней логики. Мы обязаны реализовать все методы, даже если мы просто вызываем метод декорируемого класса. С другой стороны – это «правильная» композиция вместо «неправильного» наследования.
Так мы к согласию и не пришли. А вы что скажете? Может есть вообще какой-то третий, «более лучший», вариант?
Композиция или наследование
Возникли у нас как-то с коллегой разногласия по поводу реализации одной функциональности. Лучшие практики объектно-ориентированного проектирования советуют нам предпочитать композицию наследованию. Но всегда ли это верно?
Коротко о домене. Есть у нас сервис поиска поставщиков электронных деталей, и сайт, на котором его можно осуществлять по подписке. А ещё есть сервис, который мы предоставляем производителям этих деталей. Заключается он в том, что мы даём им доступ к результатам нашего поиска «на их сайте». Чтобы на их сайте покупатель мог легко найти, какие поставщики их деталей есть рядом. Да, в наше время уже 99,9% читателей подумали бы, что мы предоставляем API, но нет. В смысле, API тоже есть, но поскольку сервису уже почти 20 лет и не у каждого производителя есть отдел разработки, который мог бы прикрутить этот API к их сайту, есть у нас и другая опция. Мы создаём страницы с функциональностью (поиск, результаты, возможность заказа и т.п.) и подгоняем их под внешний вид сайта производителя.
К сути. Конечно, каждый наш клиент хочет, чтобы функциональность максимально соответствовала его сайту. И стандартная реализация не всегда подходит. Кто-то хочет разную логику поиска: «с начала», «содержит», «равно». Кто-то разные регионы: по умолчанию результаты делятся на Америка, Европа и Азия, но некоторые просят поделить по-другому. И так далее, там настроек выше крыши. Большинство из них легко сохраняется в JSON, но не все. Например, кто-то хочет, чтоб на странице результатов поиска повторялась форма поиска, а кто-то, чтоб результаты определённого поставщика показывались сверху. Тут уже не избежать кастомной бизнес-логики.
Мы сошлись на том, что должен быть базовый класс со стандартным поведением, реализующий интерфейс. Вот его упрощённый код. Только методы, каждый из которых реализует нужный кусок функциональности (допустим, форматирует вывод):
puclic class SearchResults : ISearchResults
{
public Header GetHeader(…) { … }
public Rows GetRows(…) { … }
public Footer GetFooter(…) { … }
}
Кроме того, мы сошлись на том, что в случае, когда нужно что-то поменять, мы просто создаём отдельный класс для определённого производителя и переопределяем там нужную логику. Потом в DI-контейнере для каждого производителя внедряется либо класс по умолчанию, либо его специализированный (если он есть).
Так вот, моя реализация предполагала, что спец-класс просто наследовал бы от базового и переопределял нужную функциональность:
puclic class CustomSearchResults
: SearchResults, ISearchResults
{
public override Header GetHeader(…)
{
// кастомная логика
}
}
Остальные методы автоматически наследовались бы. Коллега настаивал на предпочтении композиции наследованию, и что мы должны делать декоратор базового класса. Как-то так:
puclic class CustomSearchResults
: ISearchResults
{
private SearchResults _base;
public CustomSearchResults(SearchResults sr)
{
_base = sr;
}
public Header GetHeader(…)
{
// кастомная логика
}
public Caption GetRows(…)
=> _base.GetRows(…);
public Caption GetFooter(…)
=> _base.GetFooter(…);
}
По мне так в декораторе куча лишней логики. Мы обязаны реализовать все методы, даже если мы просто вызываем метод декорируемого класса. С другой стороны – это «правильная» композиция вместо «неправильного» наследования.
Так мы к согласию и не пришли. А вы что скажете? Может есть вообще какой-то третий, «более лучший», вариант?
👍2