Представьте, вдруг она перестала работать — а вам даже позвонить некуда…
По такой логике AWS, Azure, Digital Ocean и любым другим поставщикам облачных услуг доверять вовсе нельзя, а надо строить свои дата-центры. Но согласитель — это ведь довольно накладно и очень редко, когда оправдано.
Я с Вами не спорю, такая вероятность естественно есть. И от отказа облачного сервиса всегда надо себя обезопасить.
Вы не думали над вариантом использования облачной распределенной базы (Cosmos DB или альтернатив) с репликацией в свою собственную(в которую не сложно перенести данные из облачной, к примеру для Cosmos DB кажется наиболее близка ArangoDB) на случай экстренного восстановления?
К примеру иметь несколько серверов для репликации, которые будут использоваться в случает отказа основной базы и писать в них чем-то вроде сервисов на Go срабатывающих на CRUD операции.
Если не совсем понятно что я пытаюсь описать — могу визуализировать.
Утверждение что Написание тестов значительно увеличивает время разработки справедливо в первую очередь если UnitTest пишется на объекты низкого уровня.
Если разработчик не парится по поводу размера юнита, а пишет тесты исходя из здравого смысла, то возможно даже и сокращает.
Я просто обожаю эту фразу, «Написание тестов значительно увеличивает время разработки». Всегда, когда слышу ее возникает чувство, что люди которые такое говорят не писали приложений сложнее автогенерируемых.
Конечно, юные разработчики, которые и программировать нормально еще не умеют, будут затрачивать больше времени на разработку при написании тестов.
Но это и не секрет, что джуны все делют или дольше или не качественнее.
Если же говорить про разработчиков, которые понимают философию тестирования и уже разобрались как пользоваться тестовым фреймвокром, то при разумном написании тестов проиводительность только повысится.
На пимере веб-приложения. Мы можем иметь класс, который обрабатывает данные с формы и выдает какой-то результат для дальнейшей обработки следующему классу.
Без теста мы можем вводить данные на форму, отправлять ее и смотреть что получим(может еще и дебажить в то же время).
С тестом мы просто введем нужные нам данные при написании теста и будем его запускать каждый раз когда хоти проверить правки.
От одного только сокращения времени на перезагруке страницы, вводде данных и ожидании ответа сервера можно выиграть не мало времени.
P.S. не подумайте, что я с Вами спорю — наоборот, поддерживаю Ваше высказывание
пишет тесты исходя из здравого смысла, то возможно даже и сокращает.
добавлю важный момент — юнит тесты должны быть максимально независимы от окружения.
К примеру, мы можем иметь один класс, но он будет работать с базой/файловой системой и если у нас базай/файловая система как-то не замокана то получим в итоге интеграционный тест.
Самый типичный пример — тестирование ActiveRecord моделей унаследованных от базового ActiveRecord. Тест как-бы будет проверять один класс, но по факту мы будет тестировать заодно и кучу компонетнов ORM.
Если не совсем понятно к чему я клоню, могу привести примеры кодом.
Вы написали, что отказались от облачных решений, но не рассматривали ли Вы перед отказом Azure Cosmos DB?
Она очень заинтересовала, но информации о ней (кроме как от Microsoft) не так то и много.
Буду благодарен если поделитесь своими соображениями, если рассматривали ее.
В идеальном мире мы с легкостью меняем фреймворк, преписываем весь говнокод во что-то прекрасное и каждый разработчик рождается специалистом.
Но реалии таковы, что во многих фирмах фреймворк выбран за разработчиков и хочешь не хочешь, а берешь то, что решили за тебя.
То же и с подходами.
К примеру, фирма конвеером клепает простенькие заказы на Yii2 и вдруг заходит что-то серьезное. Скорее всего начнут делать как для конвеера и наберут кучу проблем т.к. надо было отказаться сразу от Yii2, а скорее всего и от PHP. (это так, пример из пальца чтобы передать суть)
Все действительно упирается в варианты использования и то, что хорошо в одном случае, может быть совершенно не применимо в другом.
Насчет Name как value object с одним стандартным преобразование в строку, да это хороший вариант, для некоторых случаев избыточен но если говорить обобщенно, то я был бы рад иметь Name, Date, Status и т.п. как VO по умолчанию.
Огорчает только то, что далеко не все фраемворки (в частности ORM) дают возможности для удобной работы с VO и далеко не во всех ОО языках VO распространены и нормально поддерживатся.
представим что есть Junior или Middle разработчик. Ему дают задачу и он ее рализует основываясь на подходах принятых в текущем framework'е. Потом идет следующая задача, за ней следующая и в какой-то момент приложение разрастается, а подходы продолжают применяться как для более простого варианта и со временем все скатывается в помойку.
Действителльно припекает зачастую тем, кто получает в подарок ведро лапши.
Но добавлю, что порой даже те, кто начал варить лапшу, понимают что они наделали, но винят в этом ActiveRecord, framework и т.п. (сам грешен — так делал в прошлом)
А насчет Вашего описания проблемы с использованием ActiveRecord — я об этом и думал, но не расписал более детально как Вы.
Я имел ввиду, что зачастую ругаются на паттерны, фраемфорки и языки из-за того, что используют их не по назначению или неправильно.
Для примера и привел ActiveRecord т.к. с ним очень часто допускают ошибки и, как Вы и сказали, начинают делать лапшу из бизнес и логики хранения. В итоге получаются классы на 1500 — 4000 тысячи строк где код на все случаи жизни с переплетением бизнес правил и логики ОРМ.
Для описанных случаев я бы ни VO ни хелпер не использховал.
Собственно пример про PersonName описывался как некий простой случай, а разговор далее пошел и про интерналищацию и про разные места отображения.
Давайте разделим простые примеры и более сложные.
За простой пример давайте возьмем ситуацию, когда Person у нас не интернализируется, в отчетах не учавствует и собственоо правила форматирования имени у него всегда одни. Для такого случая, я думаю применение обычного свойства было бы уже достаточно:
public class Person
{
private string firstName;
private string lastName;
public Person(string first, string last)
{
firstName = first;
lastName = last;
}
public string Name => $"{firstName} {lastName}";
}
Другое дело, если, к примеру, нам нужно будет показывать имя Person на сайте и в отчете, применяя разные методы форматирования.
Тогда можно обратиться к адаптерам/моделям отображения или т.п., но никак не к VO и не добавлять логику для отображения и форматирования для каждого места использования в сущность. Получится что-то наподобие:
public class Person
{
public string FirstName
{ get; set; }
public string LastName
{ get; set; }
public Person(string first, string last)
{
FirstName = first;
LastName = last;
}
}
public class WebPerson
{
private Person person;
public Person(Person personEntity)
{
person = personEntity;
}
public string Name => $"{personEntity.FirstName} {personEntity.LastName}";
}
public class ReportPerson
{
private Person person;
public Person(Person personEntity)
{
person = personEntity;
}
public string Name => $"First Name: {personEntity.FirstName} | Last Name: {personEntity.LastName}";
}
А если добавится интернализация, что-то наподобие:
public class InternationalPerson
{
private Person person;
public Person(Person personEntity)
{
person = personEntity;
}
public string Name => PersonNameFormatter.format(person);
}
Не подумайте, что вышеприведенные примеры являются однозначно правильным путем для реализации. Это просто псевдо-С# код который показывает общую идею.
Я хочу сказать, что операции над данными сущности не обязательно должны быть в самом классе сущности но это и не значит, что их все надо выносить в сервисные классы.
Как уже сказал VolCh, сущности не должны отвечать за свое отображение.
В сущности должен находиться код, который работает с данными сущности в рамках бизнес логики.
К примеру, подобные методы вполне могут быть в сущности или VO сущности:
Классическое ООП = «Rich Data Model» = антипаттерн.
Это заявление выглядит как типичное «ваше ООП отстой, а вот ФП — это круто».
Говнокодище пишут и на ООП языках и на ФП — проблема, в основном, в людях, а не в ООП или ФП.
К примеру, люди берут типичный MVC framework для Enterprise системы, засовывают всю бизнес логику в AcctiveRecord, а потом мы видим тысячи гневных отзывов о AcctiveRecord.
Но в то же время тысячи людей используют типичный MVC framework с AcctiveRecord для небольших систем и вполне себе счастливы, а заказчик получает новый фичи по рассписанию.
Так вот, не в AcctiveRecord проблема у первых, а в них самих. Каждый шаблон, методология и язык применимы для решения определенного ряда задач и если попытаться выйти за рамки применения то сразу начнутся проблемы.
Возможно данная книга сыграла важную роль в популяризации «паттернов». Сложно сейчас рассуждать об этом.
Но во когда смешивают «паттерны» и «шаблоны» в одном контексте — вот это я считаю плохим тоном.
Я предпочитаю использовать или английский термин или перевод, но не все вместе — считаю что от этого получается какая-то каша.
Посмею заявить, что не С++ программисты не имеют ничего против слов «шаблон» и «анти-шаблон».
Абсолютно соглашусь, что паттерн и антипаттерн стали обычными разговорными словами у разработчиков но, на сколько мне известно, во многих вузах преподаватели говорят «шаблон», а не «паттерн».
По крайней мере когда я учился то преподаватели еще импользовали слово «шаблон».
Собственно начинающие разработчики скорее всего будут знать «шаблоны», а не «паттерны».
Да и людям, которые слабо знакомы с английским и только начинают познавать азы проектирования, слово «шаблон» будет более знакомо нежели «паттерн»(по крайней мере так было у многих людей с которыми мне доводилось общаться)
P.S. не подумайте что я с Вами спорю — просто хотелось изложить свою точку зрения и наблюдения.
А почему Вы не рассматривали «Chef»?
Помимо того, что он тоже не «на питоне» были еще какие-то аргументы?
Мы сейчас задумываемся о внедрении системы управления окружением, но больше смотрим в сторону Chef.
Chef кажется довольно продвинутым и гибким решением.
Я разрабатываю библиотеку, которая будет использовать уже сущесутвующий слой доступа к данным для реализации сущностей и репозиториев.
Делать свой собственный слой для получения данных под конкретный фраемворк, у которого этот слой уже реализован — это довольно сложная задача и врядли стоит тратить на это силы.
Моя основная идея — максимально использовать уже имеющуяся функциональность дабы не изобретать велосипеды.
К примеру в YII2 для ActiveRecord имеются такие поведения как ActiveRecord Role и ActiveRecord Variation, которые можно использовать для более гибкого построения модели предметной области.
К примеру: мы можем на уровне базы иметь таблицы «user» и «user_profile» для хранения основной (ник, почта и т.п.) информации о пользователе и его профиль (полное имя, день рождения и т.п.).
Сущность User в предметной области включает данные из обеих таблиц и для сущности не имеет значения как эти данные хранятся и что они разделены на несколько таблиц для обеспечения более оптимальной работы системы, построения отчетов и т.п.
С помощью «ActiveRecord Role» мы можкм отразить обе таблицы на одну сущность User средствами ActiveRecord и получить свою сущность предметной области абстрагированную от источника данных.
Вы абсолютно правы, но там где в одном случае все удобно, в другом это удобство может быть надгробием.
Я это говорю из собственного опыта — уже не один проект встречал, где все из «AR довольно удобен.» перерастало в «все пропало Михалыч».
В основном это происходило из-за увеличения сложности предметной области, а из-за подходов заложенных при первоначальном использовании AR уже довольно сложно было что-то менять.
Как говорится: «раз на раз не приходится». Проекты разные и то, что хорошо для большинства может быть убийцей.
P.S. Надеюсь я правильно понял о чем Вы, а то не до конца понятно к какому именно комментарию Ваш ответ.
По такой логике AWS, Azure, Digital Ocean и любым другим поставщикам облачных услуг доверять вовсе нельзя, а надо строить свои дата-центры. Но согласитель — это ведь довольно накладно и очень редко, когда оправдано.
Я с Вами не спорю, такая вероятность естественно есть. И от отказа облачного сервиса всегда надо себя обезопасить.
Вы не думали над вариантом использования облачной распределенной базы (Cosmos DB или альтернатив) с репликацией в свою собственную(в которую не сложно перенести данные из облачной, к примеру для Cosmos DB кажется наиболее близка ArangoDB) на случай экстренного восстановления?
К примеру иметь несколько серверов для репликации, которые будут использоваться в случает отказа основной базы и писать в них чем-то вроде сервисов на Go срабатывающих на CRUD операции.
Если не совсем понятно что я пытаюсь описать — могу визуализировать.
Я просто обожаю эту фразу, «Написание тестов значительно увеличивает время разработки». Всегда, когда слышу ее возникает чувство, что люди которые такое говорят не писали приложений сложнее автогенерируемых.
Конечно, юные разработчики, которые и программировать нормально еще не умеют, будут затрачивать больше времени на разработку при написании тестов.
Но это и не секрет, что джуны все делют или дольше или не качественнее.
Если же говорить про разработчиков, которые понимают философию тестирования и уже разобрались как пользоваться тестовым фреймвокром, то при разумном написании тестов проиводительность только повысится.
На пимере веб-приложения.
Мы можем иметь класс, который обрабатывает данные с формы и выдает какой-то результат для дальнейшей обработки следующему классу.
Без теста мы можем вводить данные на форму, отправлять ее и смотреть что получим(может еще и дебажить в то же время).
С тестом мы просто введем нужные нам данные при написании теста и будем его запускать каждый раз когда хоти проверить правки.
От одного только сокращения времени на перезагруке страницы, вводде данных и ожидании ответа сервера можно выиграть не мало времени.
P.S. не подумайте, что я с Вами спорю — наоборот, поддерживаю Ваше высказывание
К примеру, мы можем иметь один класс, но он будет работать с базой/файловой системой и если у нас базай/файловая система как-то не замокана то получим в итоге интеграционный тест.
Самый типичный пример — тестирование ActiveRecord моделей унаследованных от базового ActiveRecord. Тест как-бы будет проверять один класс, но по факту мы будет тестировать заодно и кучу компонетнов ORM.
Если не совсем понятно к чему я клоню, могу привести примеры кодом.
Вы написали, что отказались от облачных решений, но не рассматривали ли Вы перед отказом Azure Cosmos DB?
Она очень заинтересовала, но информации о ней (кроме как от Microsoft) не так то и много.
Буду благодарен если поделитесь своими соображениями, если рассматривали ее.
В идеальном мире мы с легкостью меняем фреймворк, преписываем весь говнокод во что-то прекрасное и каждый разработчик рождается специалистом.
Но реалии таковы, что во многих фирмах фреймворк выбран за разработчиков и хочешь не хочешь, а берешь то, что решили за тебя.
То же и с подходами.
К примеру, фирма конвеером клепает простенькие заказы на Yii2 и вдруг заходит что-то серьезное. Скорее всего начнут делать как для конвеера и наберут кучу проблем т.к. надо было отказаться сразу от Yii2, а скорее всего и от PHP. (это так, пример из пальца чтобы передать суть)
Все действительно упирается в варианты использования и то, что хорошо в одном случае, может быть совершенно не применимо в другом.
Насчет Name как value object с одним стандартным преобразование в строку, да это хороший вариант, для некоторых случаев избыточен но если говорить обобщенно, то я был бы рад иметь Name, Date, Status и т.п. как VO по умолчанию.
Огорчает только то, что далеко не все фраемворки (в частности ORM) дают возможности для удобной работы с VO и далеко не во всех ОО языках VO распространены и нормально поддерживатся.
представим что есть Junior или Middle разработчик. Ему дают задачу и он ее рализует основываясь на подходах принятых в текущем framework'е. Потом идет следующая задача, за ней следующая и в какой-то момент приложение разрастается, а подходы продолжают применяться как для более простого варианта и со временем все скатывается в помойку.
Разработчик делает вывод, что виноват framework.
Действителльно припекает зачастую тем, кто получает в подарок ведро лапши.
Но добавлю, что порой даже те, кто начал варить лапшу, понимают что они наделали, но винят в этом ActiveRecord, framework и т.п. (сам грешен — так делал в прошлом)
А насчет Вашего описания проблемы с использованием ActiveRecord — я об этом и думал, но не расписал более детально как Вы.
Я имел ввиду, что зачастую ругаются на паттерны, фраемфорки и языки из-за того, что используют их не по назначению или неправильно.
Для примера и привел ActiveRecord т.к. с ним очень часто допускают ошибки и, как Вы и сказали, начинают делать лапшу из бизнес и логики хранения. В итоге получаются классы на 1500 — 4000 тысячи строк где код на все случаи жизни с переплетением бизнес правил и логики ОРМ.
Собственно пример про PersonName описывался как некий простой случай, а разговор далее пошел и про интерналищацию и про разные места отображения.
Давайте разделим простые примеры и более сложные.
За простой пример давайте возьмем ситуацию, когда Person у нас не интернализируется, в отчетах не учавствует и собственоо правила форматирования имени у него всегда одни. Для такого случая, я думаю применение обычного свойства было бы уже достаточно:
Другое дело, если, к примеру, нам нужно будет показывать имя Person на сайте и в отчете, применяя разные методы форматирования.
Тогда можно обратиться к адаптерам/моделям отображения или т.п., но никак не к VO и не добавлять логику для отображения и форматирования для каждого места использования в сущность. Получится что-то наподобие:
А если добавится интернализация, что-то наподобие:
Не подумайте, что вышеприведенные примеры являются однозначно правильным путем для реализации. Это просто псевдо-С# код который показывает общую идею.
Я хочу сказать, что операции над данными сущности не обязательно должны быть в самом классе сущности но это и не значит, что их все надо выносить в сервисные классы.
Как уже сказал VolCh, сущности не должны отвечать за свое отображение.
В сущности должен находиться код, который работает с данными сущности в рамках бизнес логики.
К примеру, подобные методы вполне могут быть в сущности или VO сущности:
Надеюсь мой посыл понятен. Если нет, я приведу примеры получше.
Это заявление выглядит как типичное «ваше ООП отстой, а вот ФП — это круто».
Говнокодище пишут и на ООП языках и на ФП — проблема, в основном, в людях, а не в ООП или ФП.
К примеру, люди берут типичный MVC framework для Enterprise системы, засовывают всю бизнес логику в AcctiveRecord, а потом мы видим тысячи гневных отзывов о AcctiveRecord.
Но в то же время тысячи людей используют типичный MVC framework с AcctiveRecord для небольших систем и вполне себе счастливы, а заказчик получает новый фичи по рассписанию.
Так вот, не в AcctiveRecord проблема у первых, а в них самих. Каждый шаблон, методология и язык применимы для решения определенного ряда задач и если попытаться выйти за рамки применения то сразу начнутся проблемы.
Но в этих новостях есть и хорошие стороны — мы теперь знаем о проблемах и можем себя обезопасить или хотябы подготовиться.
Главное, чтобы «как год начнешь, так его и проведешь» не сработало для IT.
Но во когда смешивают «паттерны» и «шаблоны» в одном контексте — вот это я считаю плохим тоном.
Я предпочитаю использовать или английский термин или перевод, но не все вместе — считаю что от этого получается какая-то каша.
Абсолютно соглашусь, что паттерн и антипаттерн стали обычными разговорными словами у разработчиков но, на сколько мне известно, во многих вузах преподаватели говорят «шаблон», а не «паттерн».
По крайней мере когда я учился то преподаватели еще импользовали слово «шаблон».
Собственно начинающие разработчики скорее всего будут знать «шаблоны», а не «паттерны».
Да и людям, которые слабо знакомы с английским и только начинают познавать азы проектирования, слово «шаблон» будет более знакомо нежели «паттерн»(по крайней мере так было у многих людей с которыми мне доводилось общаться)
P.S. не подумайте что я с Вами спорю — просто хотелось изложить свою точку зрения и наблюдения.
Поэтому я и написал:
Насчет Puppet хотябы был аргумент:
а про Chef ничего не сказано.
Помимо того, что он тоже не «на питоне» были еще какие-то аргументы?
Мы сейчас задумываемся о внедрении системы управления окружением, но больше смотрим в сторону Chef.
Chef кажется довольно продвинутым и гибким решением.
Извините, я Вас неправильно понял. В этом я с Вами абсолютно согласен и собственно сам об этом и говорил=)
В данном случае, как я уже говорил:
Делать свой собственный слой для получения данных под конкретный фраемворк, у которого этот слой уже реализован — это довольно сложная задача и врядли стоит тратить на это силы.
Моя основная идея — максимально использовать уже имеющуяся функциональность дабы не изобретать велосипеды.
К примеру в YII2 для ActiveRecord имеются такие поведения как ActiveRecord Role и ActiveRecord Variation, которые можно использовать для более гибкого построения модели предметной области.
К примеру: мы можем на уровне базы иметь таблицы «user» и «user_profile» для хранения основной (ник, почта и т.п.) информации о пользователе и его профиль (полное имя, день рождения и т.п.).
Сущность User в предметной области включает данные из обеих таблиц и для сущности не имеет значения как эти данные хранятся и что они разделены на несколько таблиц для обеспечения более оптимальной работы системы, построения отчетов и т.п.
С помощью «ActiveRecord Role» мы можкм отразить обе таблицы на одну сущность User средствами ActiveRecord и получить свою сущность предметной области абстрагированную от источника данных.
Вы абсолютно правы, но там где в одном случае все удобно, в другом это удобство может быть надгробием.
Я это говорю из собственного опыта — уже не один проект встречал, где все из «AR довольно удобен.» перерастало в «все пропало Михалыч».
В основном это происходило из-за увеличения сложности предметной области, а из-за подходов заложенных при первоначальном использовании AR уже довольно сложно было что-то менять.
Как говорится: «раз на раз не приходится». Проекты разные и то, что хорошо для большинства может быть убийцей.
P.S. Надеюсь я правильно понял о чем Вы, а то не до конца понятно к какому именно комментарию Ваш ответ.