Pull to refresh
-14
darkit@darkitread⁠-⁠only

User

Send message

А какая разница для прикладного программиста, как там внутри происходит магия, главное чтобы все работало :)
Плюс работа ведется с домеными обьектами и всегда есть возможность спустится на уровень ниже и самому написать запрос или вообще имплементацию метода.

Так вот на мой взгляд это все усложнит код вместо тупого и прямого использование репозиториев которые вы можете отнаследовать от какого то базового который дает стандартные методы get/save/…
Посмотрите на Спринг Дата Репозиторий там вообще кода может не быть даже SQL:


public interface OrderRepository extends PagingAndSortingRepository<Order, Long> {
    List<Order> findByCustomer(Customer customer);
}

и все — у вас есть для сущности Ордер весь стандартный набор операций плюс кастомный поиск по заказчику и все это гибко без статических методов и выдумывания что делать если надо изменить имплементацию метода.

А потом добавится еще три новых поля и вы пойдете переписывать все слои. Вместо того чтобы добавить эти параметры в ДТО и изменения затронут только те части где работы с этими новыми параметрами нужна.

Второй вариант состоит в том, чтобы добавить к Db возможности редиса и переопределить (где угодно) Get и ByIdRequired как Get(this Db channel, ...) и уже внутри него различать что — в базу, что — в редис.

Это уже не чистая архитектура.
Также у вас интерфейс начнет со временем разбегаться тк редиса захочется использовать чисто его плюшки.

Смотрите у вас код в сервисе вот такой From<Db>().Get<MeasurementUnit>().ByIdRequired(id) и Db может использоваться для работы еще с какими то ентити. Те мы жестко зафиксировали канал в коде. И теперь перенеся Unit ентити в Редис канал(который мы реализовали) мы получаем что все ентити по прежнему достаются из Db а за Юнитом надо идти уже по другому From<Redis>().Get<MeasurementUnit>().ByIdRequired(id)


Верно я понимаю?


Если да то вот про это прибивание гвоздями я и говорю что сервис обьект должен знать про конкретную имплементацию канала для каждой ентити.


А что делать если ентити надо писать и в Редис и ДБ? А читать из Редиса сперва а только потом из ДБ?

Ладно, мне не сложно рассказать.

Первая часть вашего комментария отличная. Спасибо


Я так понимаю, что ваш вопрос состоял в том, что случится при переходе к Mongodb. Отвечаю: скорее всего у вас поменяется набор плюшек у канала, потому что Mongo не является реляционной БД и работать с ней надо другими средствами.

Вот поэтому у нас и есть объект репозиторий который скрывает имплементацию и все сервисы с ним работающие не знают ничего про его внутренности. А у вас получается что архитектура намертво сбитая где изменения одного слоя автоматически означают изменения в других слоях. Что в моем понимании не есть идеальная архитектура.


И на моей практике надо было делать как полную миграцию с Монги на Постгрес так частичную — часть мы пишем в Постгрес, а часть в Редис. И это было не больно, когда нормально сделаные слои и IoC.

Почему вместо них что?

поправил :) — почему вместо них просто строки.


Я полагаю, документация по EF расскажет об этом лучше и подробнее чем я.

спасибо за разъяснение.


ровно то, о чём я писал в статье когда говорил про длинные портянки IoC.

Тем самым вы приколачиваете свои сервис классы к конкретной имплементации сторадж для конкретного ентити. И как только у вас возникнет нужда один (или все) перевести с <Db> на <Mongo> вам придется править весь проект включая тесты которые по хорошему для тестирования бизнес логики и не должны меняться.

Возможно, я смотрю по примерам что есть и ассоциатирую со статьей.Что внутри фреймворка простым программистам зачастую фиолетово. Главное как жить с этим фреймворком.
а там куда не ткни везде вопросы


public void RenameMeasurementUnit(int id, string name, string shortName)
        {
            var unit = From<Db>().Get<MeasurementUnit>().ByIdRequired(id);
            unit.Name = name;
            unit.ShortName = shortName;
            To<Db>().Update(unit, x => x.Name, x => x.ShortName);
        }

где ДТО, почему вместо них просто строки?
как добавить кеш и ее инвалидацию?
как сделать оптимистик локинг?
почему вы считаете что это From<Db>().Get<MeasurementUnit>().ByIdRequired(id) гораздо лучше и проще чем measurementUnitRepository.getById(id). Потому я считаю что Сервис класс не должен знать про никакой <Db> это не его забота как получают и сохраняют MeasurementUnit а забота репозитория для этого обекта. Потому что однажды вы захотите вынести какую нить сущность в Монго например и вот мы начинаем менять по всем сервисам From<Db> на From<Mongo>


Если статья называется Я десять лет страдал от ужасных архитектур в C# приложениях — и вот нашел, как их исправить то код должен быть чтобы комар носа не подточил.

Не только на Джава, но к Шапру имею отдаленное представление. Зачем глубоко понимать Шарп если вот здесь явно видно что вы идете в базу проверяете нет ли такого measurement unit а потом сохраняете. И это неверно тк вы не сможете гарантировать что после того как вы проверили данные другая транзакция не вставит такой же юнит.

Потому что он подтверждает корректную работу реального бизнес-сценария

тестконтейнеры это не юнит тесты. Я подымаю в них постгрес, редис, кафку и начинаю гонять интеграционные тесты. Когда надо сделать бизнес сценарий то можно взять или spock или cucumber или не заморачиваться и просто JUnit и вынести каждый бизнес сценарий в отдельный класс и разбить по тест методам на которые навесить аннотации очередности.


он ещё в разработке, как и сам инструмент

проблема в том что я смотря на код и примеры в плейграунде не вижу легкости и желания работать с этим инструментом. Вот пример спринг дата с еще накрученым кешом сверху. Любой программист поймет что здесь к чему и проще уже некуда.
А у вас то вылазят статик методы а значит все гвоздями прибито, или как вкорячить Редис для персистент стораджа?
Что будет если я два раза добавлю where тут


public IQueryFor<TEntity> That(Expression<Func<TEntity, bool>> @where)
        {
            _thatExpressions.Add(@where);
            return this;
        }

или вот здесь зачем приведение к типу? это уже bad smell для меня.


internal T Key<T>(IAddition<IPrimaryKey<T>> keyedAddition)
        {
            var a = (Add)keyedAddition;
...

Такой код вообще подразумевает что речи о конкурентных запросах не может идти тк толку от проверки на уникальность в коде нет.


Те вы пишите статью с провокационным названием и наполнением заставляющим задуматься, а реализация вызывает недоумение.

В мире шарпа я вообще ничего не знаю, но ради интереса посмотрел код и… останусь я пожалуй в мире джавы и дальше, где все просто и нет у меня боли когда использую Spring или Quarkus или Guice.


Тесты — вот такие портянки я вообще даже не хочу пытаться понять. Лучше я и дальше буду работать с тестконтейнерами, моками и другими библиотеками.


Вот такой класс ошибки это нормально? Где информация типа код ошибки, sql вызвавший ошибку и тд.


У нас принято использовать liquibase или flyway и мне больно видеть вот такое


Метод в сервисе public IAddition<MeasurementUnit> CreateMeasurementUnit(string name, string shortName) — а может стоит использовать домен модели или ДТО какой то? Вы расказываете как все плохо сейчас, но вот такой код приводит что CreateMeasurementUnit("Name #1", "Name #1") непонятно что он принимает просто глядя на метод, легко перепутать аргументы.


Вот этот код


if (Aux.IsTracingNeeded)
            {
                if (!Aux.IsEvaluationNeeded)
                {
                    Aux.Query(hash, "test data", "ORM Addition PK retrieval");
                }
                else
                {
                    Aux.Query(hash, result, "ORM Addition PK retrieval");
                }
            }

что он вообще делает в Features/Reinforced.Tecture.Features.Orm.Query.cs, как это относится к методу, или SOLID это тоже плохо? А что будет если у меня пойдет мультипотоковость и я параллельно буду операции делать ?


Для меня код на Хаскеле понятней чем ваш на шарпе. И я точно бы не захотел чтобы мне пришлось работать с таким велосипедом.

Да интересно, жаль что я пока связан с aws jdk aka corretto образом и попробовать новые ГЦ в боевых условиях пока не получается :(

Оверхед в в Яве во времени старта, «прогрева» и потреблении памяти.

Да есть такое, но мы можем взять GraalVM и у нас будет бинарник с быстрым стартом.
По поводу памяти, на каком нить синтетическом тесте где Го все алоцирует на стеке конечно будет большая разница. Насколько будет разница будет в реальном мире — я не знаю, не сравнивал. Если у вас есть сравнения и исходники то я буду благодарен.


Но если у нас все упирается в память то давайте возьмем Раст или разница в год на 1Гб памяти в AWS будет около 90$. Это для хорошего калифорнийского програмиста будет меньше часы работы.


А по сложности языков лично я Го и Яву плюс минус считаю одинаковыми.

Да я тоже так примерно считаю.


P.S. Таргетинг: Го создан как замена Явы, Гугл vs Оракл в энтерпрайзе.

А вот тут проблема, поскольку бизнес логику на Го писать неудобно. Поскольку там не нужны горутины, а нужны способы выразить разные абстракции. А в Го с этим проблематично :( Ни генериков, ни тип-сум, чуть в сторону и торчат уши interface{}


Или как вы будете реализовывать на Го


type User struct {
    FirstName String
    LastName String
}

но так чтобы он был имутабельный, создавать его можно было с определенным набором данных чтобы быть уверенным что там всегда лежат правильные данные и мы могли читать его свойства FirstName/LastName


Вот пример на Джаве


@Getter
public final class User {
  private final String firstName;
  private final String lastName;

  public User(String firstName, String lastName) {
     ..../validate
     this.firstName = firstName;
     this.lastName = lastName; 
  }
}

и это мне гарантирует что никто его не изменит, никто не подсунет в метод другую имплементацию этого класса, объект будет всегда создан валидным и при этом все могут читать его свойства(это мы еще брали модули с ждк9, где вообще можно разделить доступ).


Вот недавняя статья про Го и чистую архитектуру. Как по мне то для 2020 года такой код выкладывать как эталон чистой архитектуры это печально :(

Давайте и я попробую в последний раз написать как я вижу нашу беседу:


Вы:


VM Java создает не нужный оверхед при исполнении и при разработке.

нет ни каких либо примером или фактов, на что я вам отвечаю


На Джаве программы пишутся быстрее чем на Го. Взять например простой рест ендпоинт который ассинхронный и что то читает с базы и отдает потом жсон наружу. в Джаве со спрингом это будет буквально две строчки кода, в Го я думаю вам придется написать их гораздо больше.

те я готов подтвердить свое утверждение что на Джава я напишу быстрее вот такое чем вы на Го. Я не говорил что должны писать только на чистом Го из коробки без всяких библиотек и так же если я говорю что буду брать спрингбут то это подразумевает что вы вольны брать любую библиотеку тоже.


Ваш ответ


Натянутый пример.
Все упирается в том какие готовые инструменты (библиотеки и пр.) вы используете.

Те вы вместо того чтобы согласиться и показать мне как надо, рассказываете что задание ужасное и вообще все дело в спрингбуте. Так как это соотносится с вашим самым первым сообщением где Джава тормоз в разработке если на все мои попытки ее посрамить вы уходите в какие то разговоры ?


Потом я пытался вам сказать, что бизнесу пофиг на все наши терки, ему главное какая стоимость разработки его пожеланий. И если кто то может делать на готовых кубиках, так это только отлично. Это я к тому, что в реальном мире надо рассматривать эко-системы Джавы и Го целиком, А не считать, что в чистом Го есть горутины а Джаве только системные потоки и значит на Джаве нельзя сделать что либо кроме Thread per Request.


Дальше вы обиделись и начали меня называть тролем.


Поэтому, в который раз, чтобы не флудить словами, а доказать делом мы с вами сделаем вот такой проект и сравним сколько времени заняло, сколько строк кода получилось, какую нагрузку держит и сколько памяти жрет. Это будет лучше чем тысячи слов.

Вот ваше сообщение
в нем нет ни каких фактов, ни примеров, есть только надо быть как Гугл и делать все на Го, а Джава и Раст тормоз в разработке, а Джава так еще и тормоз в рантайме.


Мои предложения о том, что взять и сделать что то одинаковое и потом сравнить, вы просто игнорируете.
Но троль я :))))))


Хорошего вам вечера.

Я могу взять SpringBoot, а могу Quarkus и сделать через GraalVM готовый бинарник. Могу взять Azul GC или вообще без ГЦ запускать. Те с Джава я могу покрыть огромное кол-во use case оставаясь в рамках одной системы и мне не надо менять ни утилиты для работы ни разработчиков. Или взять node.js и тайпсрипт и быть в гармонии на фронтенде и бекенде.


А про Го мне приходится допытываться хоть про какую конкретику.

Я не решил как раз, я вам банальный пример привел


На Джаве программы пишутся быстрее чем на Го. Взять например простой рест ендпоинт который ассинхронный и что то читает с базы и отдает потом жсон наружу

и вы сказали что это не показатель потому что я буду использовать что то готовое а это не честно. Теперь вы говорите что на Го надо брать библиотеки.


Ну тогда давайте вы покажите пример проекта на Го в котором будет простой ендпоинт который будет ходить в Редис за данными в какой нить лист и отдавать жсон этого листа наружу. Так же проект обернуть тестами с моками для сервис layer и какими нить интеграционными для хождения в Редис. И все должно тестироваться и собираться и потом создавать докер образ — причем под Линуксом/Виндовс/Мак чтобы разработчики могли это все локально собирать и смотреть.


и мы сравним с таким же проектом от меня. и посмотрим кто сколько времени потратил и какой код на выходе получился.

Это имеет отношении к реальности. Если я решаю задачи бизнеса за Х денег на Джаве, а вы за Х*2 на Го, то бизнес не будет волновать, что я читер и взял спрингбут и погнали, а вы с нуля на чистом Го реализовываете весь стек.


П.С. И я все еще хочу увидеть типичный пример микро-сервиса который на Джаве будет тормознутым, а на Расте его реализовать потребуется куча времени, а реализация Го будет быстра и в разработке и рантайме.

Почему натянутый? по большому счету большинство микро-сервисов получили запрос, куда то сходили за данными, как то их по преобразовывали и вернули результат.


Ну или вы скажите пример какой типичный микросервис будет писаться быстрее на Го а на Джаве или Расте это будет ужас ужас.

Information

Rating
Does not participate
Registered
Activity