powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Java [игнор отключен] [закрыт для гостей] / Как защитить код
25 сообщений из 76, страница 2 из 4
Как защитить код
    #39870128
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaАндрей Панфилова зачем удалять?
сеньор-то - пьяный. а в коде на Scala он и трезвый побоится удалять, разве что все скопом ;)

В ФП фишка в том что компилятор за тебя контролирует типы,и да, ты не сможешь удалить вызов транзактора и при этом не поломать сборку.
...
Рейтинг: 0 / 0
Как защитить код
    #39870129
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTmaytonЯ-бы ограничился обычным каментом. Типа - "Перед тем как удалять - хорошо подумай. Если все таки решил удалять подойди
к Atum и спроси разрешения".

Все. Баста. Решение на 0.001 story point.
ща мода пошла у некоторых не писать вообще принципиально никаких комментов по коду. потому что мартин так в своей книжке чистый код сказал. ))) у узбеков есть поговорка - попроси принести тюбетейку - они тебе принесут тюбетейку вместе с головой.
Плохая мода.

Но Роб Мартин прав в части того что каменды надо также суппортить как и код.
...
Рейтинг: 0 / 0
Как защитить код
    #39870130
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTповедение кода закрепляют тесты. ответ - надо покрыть код тестами.

Лучший тест - это компиляция, которую не забудешь проранать
...
Рейтинг: 0 / 0
Как защитить код
    #39870143
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никНикак, но в этом и весь цимус, что вам это и не надо.
Чет какая-то жесть...
- проблема: очень печально что мы не видим где транзакция начинается (в endpoint транзакции начинаются по канону)
- решение: берем скалу, теперь мы все равно не знаем где начинается транзакция, но проблемы уже нет - теперь у нас жопа в другом месте

забыл никА чтобы выполнить ConnectionIO - ты обязан предоставить Transactor, иначе не скомпилируется.Как по мне так никакой практической пользы тут нет, транзакции же определяют как мы должны работать с данными, а тут нам язык какую-то конвенцию придумывает. А что делать если определенное метод мне нужно вне транзакции запустить, а если нужно параллельную транзакцию открыть?
...
Рейтинг: 0 / 0
Как защитить код
    #39870164
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ПанфиловЧет какая-то жесть...
- проблема: очень печально что мы не видим где транзакция начинается (в endpoint транзакции начинаются по канону)
- решение: берем скалу, теперь мы все равно не знаем где начинается транзакция, но проблемы уже нет - теперь у нас жопа в другом месте


Да с чего вдруг? На самом деле идея простая, но не сразу дается, когда переходишь со спринга(сам так тупил)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
UserService{
def insertUser = ... return Connection[User] 
def updateAudit = ... return Connection[Boolean]
}

MailService{
sendEmail = ... return IO
}

UserController(transactor:Transactor)

def insertUser = {
   val useCase:Connection[String] = for {
      user <- UserService.insert
      result <- UserService.audit
      _ <- if(result) MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}

def insertUserNoAudit = { 
   val useCase:Connection[String] = for {
      user <- UserService.insert
      _ <- MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}



В целом - sendEmail, insertUser - маленькие кусочки реюзаемой логики, никаких cross-cutting concerns.
В Контроллере ты компонуешь эти кусочки как вздумается, и когда тебе нужен результат(а не дескрипшен твоего действия) - передаешь туда транзактор, обычно это как раз в эндпоинтах контроллера.
...
Рейтинг: 0 / 0
Как защитить код
    #39870169
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ПанфиловКак по мне так никакой практической пользы тут нет, транзакции же определяют как мы должны работать с данными, а тут нам язык какую-то конвенцию придумывает. А что делать если определенное метод мне нужно вне транзакции запустить, а если нужно параллельную транзакцию открыть?

Выполнить кусок кода вне транзакции не получится в любом случае. Если нужна параллельная - ну вызывай в другом потоке, транзактор тредсейф. А вообще звучит как "а ваша пила умеет сталь пилить?", хотелки какие-то непонятные, хотя прикол в том, что даже их без проблем можно реализовать
...
Рейтинг: 0 / 0
Как защитить код
    #39870188
Андрей Панфилов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никАндрей ПанфиловЧет какая-то жесть...
- проблема: очень печально что мы не видим где транзакция начинается (в endpoint транзакции начинаются по канону)
- решение: берем скалу, теперь мы все равно не знаем где начинается транзакция, но проблемы уже нет - теперь у нас жопа в другом месте


Да с чего вдруг? На самом деле идея простая, но не сразу дается, когда переходишь со спринга(сам так тупил)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
UserService{
def insertUser = ... return Connection[User] 
def updateAudit = ... return Connection[Boolean]
}

MailService{
sendEmail = ... return IO
}

UserController(transactor:Transactor)

def insertUser = {
   val useCase:Connection[String] = for {
      user <- UserService.insert
      result <- UserService.audit
      _ <- if(result) MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}

def insertUserNoAudit = { 
   val useCase:Connection[String] = for {
      user <- UserService.insert
      _ <- MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}



В целом - sendEmail, insertUser - маленькие кусочки реюзаемой логики, никаких cross-cutting concerns.
В Контроллере ты компонуешь эти кусочки как вздумается, и когда тебе нужен результат(а не дескрипшен твоего действия) - передаешь туда транзактор, обычно это как раз в эндпоинтах контроллера.
В данном случае (исходим из обсуждаемого примера) получается так:
чтобы дернуть MailService мне его нужно его заврапить в ConnectionIO (там в статье пишут IO.to[ConnectionIO]), поэтому везде по приведенному коду мне нужно расставить этот .to[ConnectionIO] "чтобы скомпилировалось", дальше проходит время, я выхожу из запоя и принимаю решение что почту мне нафиг посылать не нужно прямо вот сейчас, а можно и через некоторое время, поэтому я иду и меняю реализацию MailService чтобы оно писало в БД вместо отправки почты, а потом бегаю по всему коду и убираю .to[ConnectionIO] потому что теперь не компилируется - какое-то сомнительное удовольствие кмк.

забыл никВыполнить кусок кода вне транзакции не получится в любом случае. Если нужна параллельная - ну вызывай в другом потоке, транзактор тредсейф. А вообще звучит как "а ваша пила умеет сталь пилить?", хотелки какие-то непонятные, хотя прикол в том, что даже их без проблем можно реализоватьЗдрасьте, требования как требования (ну вот спринг же умеет, а он ориентирован на JSR 907, который не последние люди в мире жавы разрабатывали), да и вызов в другом потоке и открытие новой транзакции из текущего - это два совершенно разных паттерна.
...
Рейтинг: 0 / 0
Как защитить код
    #39870212
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
chpashaandreykaTне писать вообще принципиально никаких комментов по коду. потому что мартин так в своей книжке чистый код сказал
Мартин ничего не говорил про "не писать принципиально"
авторTherefore, though comments are sometimes necessary, we will expend significant energy to minimize them.


Узбекская поговорка это только подтверждает ;)
конечно не говорил. вернее, он говорил типа не пишите избыточные комменты и не пишите бесплезные комменты. но норот читает как "не пишите комменты". ))) и начинаются в ревью тёрки типа у тебя код говно потому что ты вон там коммент оставил. а не только в шапке через жавадог
...
Рейтинг: 0 / 0
Как защитить код
    #39870218
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никandreykaTповедение кода закрепляют тесты. ответ - надо покрыть код тестами.

Лучший тест - это компиляция, которую не забудешь проранать
а причем в данном случае компиль? код то работает. просто он не так работает как ожидает тс. поведение кода контролируется тестами. имхо. про ваши фп как обходиться без тестов и вообще всё само я пока не вник. не у кого поучиться )
...
Рейтинг: 0 / 0
Как защитить код
    #39870220
andreykaT
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никАндрей ПанфиловЧет какая-то жесть...
- проблема: очень печально что мы не видим где транзакция начинается (в endpoint транзакции начинаются по канону)
- решение: берем скалу, теперь мы все равно не знаем где начинается транзакция, но проблемы уже нет - теперь у нас жопа в другом месте


Да с чего вдруг? На самом деле идея простая, но не сразу дается, когда переходишь со спринга(сам так тупил)

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
UserService{
def insertUser = ... return Connection[User] 
def updateAudit = ... return Connection[Boolean]
}

MailService{
sendEmail = ... return IO
}

UserController(transactor:Transactor)

def insertUser = {
   val useCase:Connection[String] = for {
      user <- UserService.insert
      result <- UserService.audit
      _ <- if(result) MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}

def insertUserNoAudit = { 
   val useCase:Connection[String] = for {
      user <- UserService.insert
      _ <- MailService.sendEmail
   } yield "OK"
   useCase.run(transactor)
}



В целом - sendEmail, insertUser - маленькие кусочки реюзаемой логики, никаких cross-cutting concerns.
В Контроллере ты компонуешь эти кусочки как вздумается, и когда тебе нужен результат(а не дескрипшен твоего действия) - передаешь туда транзактор, обычно это как раз в эндпоинтах контроллера.

так вот он я красавец. у меня есть юзкейс.ран(транзактор), а есть скажем юзкейс.ватеварелз(неТранзактар)
и я такой модный программист - просто удаляю эту строку и подменяю другой. оно дальше допустим, работает но уже без транзакции.
...
Рейтинг: 0 / 0
Как защитить код
    #39870292
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никЕсть куда деваться. Как раз вот статья вышла хорошая, но это нужно иметь кое-какие знания о ФП чтобы понять.
Тыц

Спасибо, отличная статья. Идея о том, что из репозиториев можно возвращать DBIOAction[T] вмето Future[T] (у меня слик) и потом транзакционно интерпретировать в Application Service, лично для меня закрывает один из пробелов между классическим DDD и функциональным стилем.
...
Рейтинг: 0 / 0
Как защитить код
    #39870325
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
забыл никPetroNotC Sharpпропущено...

Но жто декларативное управление транзакциями. Мейнстрим счас. Куда деваться.


Есть куда деваться. Как раз вот статья вышла хорошая, но это нужно иметь кое-какие знания о ФП чтобы понять.
Тыц

Это конечно не совет автору все переписывать с нуля
- просто чтоб знал как бывает иначеох боюсь это никому не надо. Так как усложняет.
Надо 2 транзакции, пиши 2 потока или 2 раза beginTran.
Всё.
...
Рейтинг: 0 / 0
Как защитить код
    #39870326
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixxerфункциональным стилем.а рвзве ФП стало распространено?
...
Рейтинг: 0 / 0
Как защитить код
    #39870377
Фотография fixxer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpfixxerфункциональным стилем.а рвзве ФП стало распространено?

В скале так точно. Но даже в джаве последние три года встречаю, в основном, реактивные стримы и Completable Future.
...
Рейтинг: 0 / 0
Как защитить код
    #39870387
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixxerPetroNotC Sharpпропущено...
а рвзве ФП стало распространено?

В скале так точно. Но даже в джаве последние три года встречаю, в основном, реактивные стримы и Completable Future.
Если посмотреть более шИроко. То ФП давно уже вокруг вас. ФП - это не только программирование.
Это декларативное описание грамматик и смыслов. Формы Бекуса Науэра BNF/EBNF. Xml-schema/DTD.
Просто спеки для всяких DSL. И попытки втащить в языки программирования иммутабельность структур
данных - это всё части ФП.
...
Рейтинг: 0 / 0
Как защитить код
    #39870400
SpringMan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Atum1Любые идеи, подойдут.

Как возможный вариант - на методы дао/репозитории вешать Transactional.MANDATORY
...
Рейтинг: 0 / 0
Как защитить код
    #39870401
SpringMan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SpringManКак возможный вариант - на методы дао/репозитории вешать Transactional.MANDATORY
С каким-нибудь тестом, разумеется.
...
Рейтинг: 0 / 0
Как защитить код
    #39870427
pavel_nv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нужно понимать где у тебя в проекте вообще наставлены эти @Transactional
если это, как обычно - в контроллере для доступа к слою сервисов - то я бы сделал отдельный слой, который отвечает только транзакции совместно с мавен-модулями. напирмер

project
|
|- web (содержит контроллеры, имеет доступ только к интерфейсу core-api и DTOшки)
|
|- core api (содержит только интерфейс (какой нибудь BusinessService) и, вероятно, DTO)
|
|- core impl (содежит реализацию BusinessServiceImpl, весь класс помечен @Transactional, внутри редиректит логику уже в "настоящие" сервисы, вероятно конвертирует DTO в сущности JPA)

тут конечно "лишнего" кода будет много


Если конечно расстановка @Transactional имеет хаотичный характер - то, имхо, только интеграционные тесты) которые обращаются в систему через контроллеры
...
Рейтинг: 0 / 0
Как защитить код
    #39870462
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чувствую в этом топике рождается гоммункул.
...
Рейтинг: 0 / 0
Как защитить код
    #39870490
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Андрей ПанфиловВ данном случае (исходим из обсуждаемого примера) получается так:
чтобы дернуть MailService мне его нужно его заврапить в ConnectionIO (там в статье пишут IO.to[ConnectionIO]), поэтому везде по приведенному коду мне нужно расставить этот .to[ConnectionIO] "чтобы скомпилировалось", дальше проходит время, я выхожу из запоя и принимаю решение что почту мне нафиг посылать не нужно прямо вот сейчас, а можно и через некоторое время, поэтому я иду и меняю реализацию MailService чтобы оно писало в БД вместо отправки почты, а потом бегаю по всему коду и убираю .to[ConnectionIO] потому что теперь не компилируется - какое-то сомнительное удовольствие кмк.

Во-первых, тебе надо заворачивать MailService в ConnectionIO только в случае если ты хочешь вызвать его в рамках транзакции, в общем случае посылка email - это side-effect и должен быть обернут просто в IO. Верхний уровень программы выглядит примерно так:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
def program = {
   IO db = DBLogic.run(transactor)
   IO log = saveLog
   IO mail = MailService.sendMail
   IO result = db *> log *> mail /// Тут код все еще не выполняется мы возвращаем всего лишь IO  - аля description of computation
}


Main {
   program.runUnsafe() // Реальный код выполняется здесь, все что находилось в IO тут разворачивается в значения Int, User т.д
}



Во-вторых, ты в чем-то прав, а именно в том что надо прикладывать усилия, чтобы код скопилировался. Но это происходит именно потому что мы прописываем в типе дополнительную информацию(а именно что коду нужно DB connection) - и если он не компилируется(ты поменял реализацию MailService) - то оно и не должно компилироваться, потому что коннекшен тебе не нужен.
И это не недостаток а достоинство. Тебя же не возмущает, если ты заменишь String date на LocalDate date - и тебе надо поменять все места, где используется это поле "чтобы скомпилировалось"?

С наскока это не понять, и даже за месяц.
Никого не уговариваю, хотите верьте, хотите нет - но composable type-safe transactions существуют
...
Рейтинг: 0 / 0
Как защитить код
    #39870494
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTзабыл никпропущено...


Лучший тест - это компиляция, которую не забудешь проранать
а причем в данном случае компиль? код то работает. просто он не так работает как ожидает тс. поведение кода контролируется тестами. имхо. про ваши фп как обходиться без тестов и вообще всё само я пока не вник. не у кого поучиться )

А в том что ты в типах можешь прописать дополнительную логику. Некоторые умельцы чисто на типах пилят игры в пятнашки. И эти типы будут проверяться компилятором. И не по твоему хотению, а всегда. Их невозможно обойти и невозможно "забыть" запустить перед коммитом
...
Рейтинг: 0 / 0
Как защитить код
    #39870499
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andreykaTтак вот он я красавец. у меня есть юзкейс.ран(транзактор), а есть скажем юзкейс.ватеварелз(неТранзактар)
и я такой модный программист - просто удаляю эту строку и подменяю другой. оно дальше допустим, работает но уже без транзакции.

Не поянл, какую строку удаляешь и почему оно перестанет работать? Любая операция с базой имеет тип ConnectionIO - единственный способ вытянуть оттуда реальное значение - это предоставить транзактор. Если ты не предоставишь - у тебя будет просто объект типа ConnectionIO и ты его не сможешь никак заюзать.
...
Рейтинг: 0 / 0
Как защитить код
    #39870500
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
fixxerзабыл никЕсть куда деваться. Как раз вот статья вышла хорошая, но это нужно иметь кое-какие знания о ФП чтобы понять.
Тыц

Спасибо, отличная статья. Идея о том, что из репозиториев можно возвращать DBIOAction[T] вмето Future[T] (у меня слик) и потом транзакционно интерпретировать в Application Service, лично для меня закрывает один из пробелов между классическим DDD и функциональным стилем.

А DDD никак не противоречит ФП, а очень даже хорошо вписывается, я уже приводил линку - вот неплохая книга.

Functional-Reactive-Domain-Modeling
...
Рейтинг: 0 / 0
Как защитить код
    #39870509
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpзабыл никпропущено...


Есть куда деваться. Как раз вот статья вышла хорошая, но это нужно иметь кое-какие знания о ФП чтобы понять.
Тыц

Это конечно не совет автору все переписывать с нуля
- просто чтоб знал как бывает иначеох боюсь это никому не надо. Так как усложняет.
Надо 2 транзакции, пиши 2 потока или 2 раза beginTran.
Всё.

Что усложняет? В хорошо написанной программе - Что в ООП, что в ФП по факту будет один и тот же результат(прочитать что-то, записать, залогировать, изменить стейт системы, обработать ошибки). И тебе и там и там надо обработать ошибки, обернуть все в транзакцию, обработать отсутсвие данных и т.д. В случае ООП обычно начинается с красивого кода по happy-path, а проверки на нулл, обработка эксепшенов, всякие корнер - кейсы - это уже по мере тестирования. В случае ФП - у тебя код просто не скопилируется пока ты все это не пропишешь.
Простота ООП иллюзорна и только расслабляет программиста, провоцируя его вовремя дэдлайнов на куяк куяк и в продакшен.
...
Рейтинг: 0 / 0
Как защитить код
    #39870513
забыл ник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharpfixxerфункциональным стилем.а рвзве ФП стало распространено?
Да, идеи ФП проникают в Java, C# и т.д, а не наоборот, как минимум. Тебе 10 лет назад показать код на стримах - ты бы ворочал носом и говорил какое говно, у меня есть циклы
...
Рейтинг: 0 / 0
25 сообщений из 76, страница 2 из 4
Форумы / Java [игнор отключен] [закрыт для гостей] / Как защитить код
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]