Pull to refresh
32
0
Andrii Bui @andreyka26

Software Engineer II

Send message
Потому что она не дала вам критерия, как правильно.

Цитата автора с книги(architecture chapter): «Software was invented to be 'soft' It was intended to be a way to easily change the behavior of machines. If we'd wanted the behavior of machines to be hard to change, we would have called it hardware
To fulfill its purpose, the software must be soft — that is, it must be easy to change»
Нет. Потому что если весь код, отвечающий за выполнение сценария, находится в одном месте, то его изменение может повлиять только на этот сценарий и ни на что больше.


Я думаю зависит от сложности проекта. Если проект простенький, множества всяких либ и компонентов с сложной логикой там нет — тогда, почему нет?.. Но так или иначе, если например контролер в себе имеет логику написания чистого СКЛ к БД, это виолейшн SRP так точно. Не думаю что это хорошо.

Про сложность и независимость: Когда один екшн контролера занимает строк 400, то я думаю, для этого и придумали лейерную архитектуру(тот же самый DDD), что бы изолировать независимые между собою компоненты, что упрощает понимание, потому что конкретный компонент отправки меседжа на какой-то брокер легче понять, нежели искать куски этой логики где-то в 400 строках контроллера, может это только мне упрощает чтение и понимание логики. Если бы я увидел в каком-то сервисе, например, артиклах(представим что там ещё и серч енджайн юзается какой-нить), то если я бы увидел в контролере логику валидейшна инпута, запрос(и билдинг запроса) на серч енджайн, запрос(и билдинг запроса) на бд, логика склеивания это в оутпут, и отправку к примеру куда то ещё на другой сервис — то мне бы было сложно и неудобно с такой структурой. Противопоставлю этому пример: если бы я увидел 3 интерфейса — для серч енджайна, для бд, для отправки на внешний сервис, мне было бы легче и быстрее понять этот код, и что делает этот экшн в контроллере.

А может не захотеть, а вы уже вложили ресурсы в подготовку к этой ситуации.
ну а если внесет — ресурсы будут больше, насколько мне известно.

если вам пришлось поменять хранилище — это архитектурный косяк, или нет?
я думаю, тут однозначно сказать нельзя. Если изначально было выбрано хранилище, при том что был выбор лучше подходящего, нежели выбранное, то тогда — да. Если же к такому прибегают в следствии изменения реквайрментов от клиента, наверное — нет. Опять же вы хотите получить конкретный ответ на абстрактный вопрос. Я думаю, зависит от проекта, людей и ситуации.
По обоим этим критериям, как ни странно, архитектура с DI и разделением на слои — плохая. Потому что чтобы понять, что делается, нужно просмотреть больше кода, и чтобы изменить одну операцию, нужно изменить больше кода.


Изменить, может и больше, но чтобы осознать не повредит это ещё чему-то, не поломает ли это логику чего-то ещё — проще все-таки лейерная архитектура, в силу того, что там стараются выделить независимые компоненты, при изменении которых (в идеальных условиях) ничего сломаться не должно, по крайней мере вероятность меньше.
И в случае все логики в контроллере(вы спросили чем это плохо), нужно смотреть 100500 строк кода, что бы понять что нужно изменить, вспомнить что вообще здесь происходит. А в лейерной архитектуре — ты строго знаешь какой лейер за что отвечает — сразу идешь туда и изменяешь это там.

Получается, что книжка для вас в этом оказалась бесполезна.
Почему же? Ведь перед тем как спросить, ты думаешь сам, читаешь, возвращаешься, опять таки, к принципам книги, и подбираешь какой-то вариант. Книга дает тебе набор принципов и «инструментов» с которых можно выбрать, не читая книги можно было о чем то не знать, либо знать о чем то не очень правильно и т.д.
А я не прошу объективности, я прошу нециклических критериев того, что такое «хорошая архитектура».

Как по мне архитектура, которая дает простоту в понимании, в особенности для нового человека, и архитектура которая позволяет более быстро и безболезненно менять логику и поведение.

Ну то есть ваш критерий правильности архитектуры — «коллеги согласились»?


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

Если вас послушать, получается, что книжка про «чистую архитектуру» не дала вам ни одного (нециклического) критерия того, что же такое хорошая архитектура.

Потому что архитектура — это не стандарт, я думаю прям абсолютной объективности здесь нельзя ожидать

Давайте возьмем простые. Как вы можете проверить, что принятые вами решения — правильные?


Окей, банальный свой проект, REST, решение: инапсулировать доступ к бд, и не писать в екшене контроллера RAW SQL, следуя, как минимум SRP & DIP. Спросил коллег: «стоит ли нагромождать екшн контроллера запросами к бд скюельными», получил ответ — «не стоит». Понял, что вероятность того, что не стоит, достаточно велика по сравнению с тем, что бы писать все в екшне.
П.П.С. Стоит ли «не экспертам» заниматься архитектурой это вопрос отдельный :)

конечно не стоит, поэтому «не экспертам» такое не доверяют, но что бы стать экспертом, нужно учится, советоваться, спрашивать обсуждать и практиковать, не знаю иных способов.
И что? Почему это плохо?

Ну могу кинуть референс на СОЛИД и какие проблемы первая рекомендация может помочь решить, но думаю вы и сами найдете.
Тааак… и что является аргументами для этого «думать»? Какие критерии? Как отличить правильное решение от неправильного?
Как я бы то делал? Советовался, писал бы на форумы, думал сам бы — вот как.

Вот я и говорю: понятия не имею.
github.com/dotnet-architecture/eShopOnContainers

Ну так я говорю про конкретно те решения, которые вы приняли. Это были сложные проблемы или простые?

И такие бывали, и такие
Занятно, не находите? Утверждается, что архитектура, которая позволяет поменять хранилище, хорошая, но необходимость поменять хранилище — архитектурный косяк.


хочешь мира — готовься к войне

ну клиент, к примеру, может захотеть фичи какой-то, и из-за этого может быть придется менять хранилище, из-за того, что оно в каком-то роде не подходит
Я задал другой вопрос, если вы помните: «Гарантирует ли следование вашим «базовым принципам», что «неправильная» архитектура не получится?»


нет не гарантирует — все индивидуально, я думаю. Мне кажется никакая книга ничего гарантировать не может, просто по причине того, что ее можно не правильно понять, как минимум.

Собственно, у меня в свежем проекте есть AWS Lambda, которая шлет прямой запрос в AWS CloudSearch, отправляет событие в другую лямбду, и все это логирует. Как раз как вы описали. Это плохая архитектура? Почему?

Я говорю не за лямбду, я с этим никогда не работал. Я имел в виду сложный сервис(стандартный asp net) который имеет достаточно много логики, которая в последствии может меняться. Как минимум это будет виолейтить SRP, если написать и логирование, и запросы в бд, и ивенты на меседж брокер в екшене контроллера. Если же говорить о простой логике, я думаю можно это сделать и там. Повторяю ещё раз нету решения, которое бы подходило для всего, нужно думать что, как и где применять.

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

Ну то есть вам лично эта книжка помогла принять решения, но вы не знаете, правильные ли они?

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


Есть варианты, описаны в ещё одной книжке Designing Data-Intensive Applications.

Как вы можете проверить, что принятые вами решения — правильные?

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

Что такое «неправильная» архитектура, и как отличить ее от правильной? Гарантирует ли следование вашим «базовым принципам», что «неправильная» архитектура не получится?

Ну, например, если мы уже говорили за книжку мелкомягких и их апликейшн — тогда поясню, что я думаю, было бы плохо. Точно было бы плохо написать Raw SQL запросы прям в контролер екшене, оттуда же отправить event на message-broker и залогировать все, к примеру. И это бы противоречило принципам, описанным в книге.
И, насколько помню, забывает упомянуть что абстракции более-менее сложных штуковин обязательно протекают. И это делает половину того, что в книге, отличной пищей для ума, но быстро разваливающейся на практике если применять не сильно думая.


Солидарен.
Если заниматься программированием не сильно думая — вообще все плохо может получится.
Угу, и во всех этих вариантах у вас будут разные гарантии целостности. Дада, те самые, про которые вы только что говорили как про бизнес-требования на транзакции. Вас это не волнует, нет?

Ну так это и будет задача имплементации того репозитория, что бы при SaveChanges(), все осталось целостным, ну как мне кажется. Как я понял, фишка в том, что бы бизнес лейер об этом не думал в процессе выполнения какой-то логики

Может допускаться, да. И что? Как это помогает принимать решения?

это поможет какое-то время НЕ принимать решения.

Вы это уже говорили, и я спросил: а для чего же она полезна?


Ну как по мне набор базовых принципов, которых следует придерживаться что бы построить хотя-бы не неправильную архитектуру. Она не может покрыть всех случаев. И есть случаи, когда, мне лично, эти знания помогали в принятии одного из двух решений, не раз я видел подтверждение их в разного рода проектах. Тот же самый EShopOnContainers.

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

Так же, мне уже самому интересно, как тогда вообще строить доступ к бд, как строить абстракции над данными, или вообще не строить их? Приведите пару примеров, может личные рекомендации?
Может вы лично сталкивались с проблемами переезда с одного способа хранения на другой — поделитесь тогда опытом
я так понимаю комментатор имел в виду эту:

Подождите, сначала вы говорите, что способ хранилища данных должен полностью соответствовать требованиям бизнеса, а потом вы говорите, что именно поэтому «полного соответствия быть не может». Где-то что-то перепутано.

Не много не так выразился: может допускаться, что будут различия между моделью БД и моделью Домена. Это делается, на примере того же EShopOnContainers, как раз для абстрагирования от деталей хранилища. У ордера(может и не у него, но не суть, в какой-то ентите) должен быть адрес. И этот адрес мы можем сразу организовать как член класса этого самого ордера, хотя прямой связи может и не быть в SQL(так оно и есть, ибо там это Value object), или же мы сможем с легкостью сделать по классике, через ещё одну таблицу в SQL и реляционную связь, либо же использовать NoSQL и поместить адрес прям в ордер. Можно вообще организовать бинарные файлы, Но фишка вся будет в том, что интерфейс репозитория как возвращал ордер с адресом — так и возвращает — вот такой маленький (идеализированный) пример, понятно, что есть случаи, когда так легко сделать не получится, опять же говорю, я этого и не отрицал — книга — не панацея от всего.

П.С. про легкость перехода с SQL на NOSQL или key-value, напишу апдейт, тут с вами согласен — легким этот переход не сделать, но все же, думаю, что если это будет инкапсулировано и абстрагировано по максимуму — это сделает переезд менее болезненным. У меня нету большого опыта, что бы знать какие ситуации бывают, и насколько это сложно, ибо сам такого опыта не имел. Конкретные техники, и как лучше абстрагироваться в том или ином случае — это уже не об этом книга, на то архитекторы и получают свои тысячи зеленью и едят сыры xD
Так, а кто говорил, что эта книга подходит под все, и волшебная таблетка от всего. Так не бывает — есть частные случаи. К сожалению, я не имею того опыта, что бы спорить о практике. В тех же примерах личного жизненного опыта автора он описывал как абстракция над доступом к данным помогла избежать некоторых проблем, точнее помогла не делать лишней работы, можете лично с ними ознакомится.

В примере конкретно Майкрософтов, DDD навязывает некоторые решения, как, к примеру, о интерфейсе репозитория — потому что, это — паттерн, который и был создан для абстрагирования от доступа к данным. И он имеет свой определенный интерфейс.

Рассмотрим к примеру апдейт того же самого ордера. В репозитории. Для этого есть соответственный метод на GetOrder(), и если его не будет, то и апдейта не будет, и если способ хранения данными не позволяет достать этот ордер — то значит он не подходит. То же самое с методом репозитория на сохранение всех изменений, который призван для того, что бы в случае изменений не одной ентити, а нескольких в пределах одного агрегата — сделать это одной транзакцией (либо все, либо ничего). Это, как я понимаю. реквайрмент бизнеса, и если же такой метод не может быть представлен каким-то способом хранения данных, значит он не подходит для этой бизнес логики. Именно поэтому ДДД и говорит о том, что полного соответствия ентити в БД с ентетей из домена может и не быть.

Стоп. Вот же оно ваше «архитектурное решение», использовать паттерн repository, да еще и с конкретным интерфейсом наверняка. А вы говорите «отложить на потом». Да, а потом вы возьмете СУБД, и поймете, что ее нельзя запихнуть в тот интерфейс, который вы на первом этапе нарисовали для репозитория, и что тогда?


Я думаю, что есть организация данных — которая сама по себе навязывает способ хранения данных. Сам я, к примеру с NoSql не работал, но мне кажется, что в том конкретном случае логично понятно, что все связи в сервисе было бы проще организовать с помощью SQL-based структуре хранения данных. И если например бизнес логика навязывает один способ хранения данных как подходящий и иной — как не подходящий, может стоит использовать подходящий, а не менять бизнес логику из-за того, что работа с данными в них не вписывается?

Что в таком случае бы вы сделали? Вы предлагаете от способа хранения данных плясать и писать бизнес логику?

А что такое в этом контексте application layer, и почему его написание не приводит к принятию архитектурных решений?


Это уже DDD штука, если в двух словах — Layer, который в себе имеет Use Case'ы, делегирует все запросы с UI на Домен, и обратно и т.д.
За авторов спасиб)

И как предлагается начать с бизнес-логики, если она работает с данными из БД и других внешних источников, своим входом имеет UI, и выходом — тоже UI?

сейчас скажу в контексте только бэк-енда. Есть такая книжечка про microservices & DDD от майкрософтов, возьму пример их же проект EShopOnContainers, сервис Ordering. В домене есть некоторые Aggregate и Entities. Можно начать с них, обдумать что как и с чем должно взаимодействовать, описать логику, а в самом поведении использовать абстракцию Repository без implementation. Как-то так. Если прям нужно тестить — ну можно in memory implementation в IoC подставить. Можно так же заняться Application Layer.
Согласен, смысл только в том, если хочешь решить надо ли читать или нет, и в том, что если у тебя нету этих 3 дней — то основные мысли, кроме раскрытия темы SOLID'a — я передал тут.

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

Information

Rating
Does not participate
Location
Украина, Украина
Registered
Activity