thảo luận Clean Architecture có thật sự giúp ta code tốt hơn?

Vì vậy mà vertical slice architecture nó k giải quyết được triệt để vấn đề mà clean architecture gây ra (có thể phải switch qua lại nhiều layers khi requirement có sự thay đổi), cách để giải quyết đó là không dùng clean architecture hoặc dùng nhưng giản lược đi (giảm số lượng layers xuống).
Điểm yếu là của abtract. Nguyên tắc là chỉ tạo abtract khi thực sự cần, chứ bác đẻ ra nhiều layer - abtract thì phải chấp nhận thôi, có pros cons cả mà?
Trong slice nếu vẫn dùng clean arch thì nó vẫn có abtract thôi. Nhưng nó giúp feature A cần thì abtract, feature B không cần thì không cần abtract làm gì. Giảm thiểu tối đa việc xuất hiện abtract rồi còn gì.
 
em hiểu rồi bác, cảm ơn bác nhé.
Điểm yếu là của abtract. Nguyên tắc là chỉ tạo abtract khi thực sự cần, chứ bác đẻ ra nhiều layer - abtract thì phải chấp nhận thôi, có pros cons cả mà?
Trong slice nếu vẫn dùng clean arch thì nó vẫn có abtract thôi. Nhưng nó giúp feature A cần thì abtract, feature B không cần thì không cần abtract làm gì. Giảm thiểu tối đa việc xuất hiện abtract rồi còn gì.
 
Sẵn topic về clean architecture nên mình tiện hỏi luôn. Khi các bác dùng clean architecture thì các bác có dùng DDD để modeling business logic không? Hay vẫn theo cách cũ là data objects + xử lý trong services?
 
Chừng nào làm project hạng nặng một vài năm , hoặc bussiness xong hết rồi hoặc framework , ko thì cứ copy patse thôi , framework cho sao thì theo vậy mà làm chế cháo suy nghĩ trăng sao rôi sau này cũng xoá thôi 😹, copy&paste find&replace là quá đủ
 
Sẵn topic về clean architecture nên mình tiện hỏi luôn. Khi các bác dùng clean architecture thì các bác có dùng DDD để modeling business logic không? Hay vẫn theo cách cũ là data objects + xử lý trong services?
cái này tuỳ hoàn cảnh, em thì có, đã là DDD thì business logic k được dính với bất kỳ một cái gì liên quan đến tầng infrastructure trong đó, đó là nguyên tắc, Còn khi apply vào thực tế thì em nghĩ còn tuỳ vào điều kiện cuj thể để đưa ra quyết định
 
đây là pet project mình đang tạm setup.
1696257974414.png


Gồm có: DDD + CQRS + Clean Architecture (C#)
Có vài điều mình vẫn còn đang khá lăn tăn.
1/ DDD khá cồng kềnh, mapping giữa internal properties(getters, setters bên Java) bằng constructor --> constructor bị phình to khá nhiều nếu entity có nhiều properties
2/ để gọi là clean thực sự thì ko hẳn, vì để tháo bớt depedency từ Domain Layer thì lại dùng interface để "cheat" dependency diagram.
3/Khi thử sử dụng DDD, khi load cả AggregateRoot (nhiều entities) lên memory thì kinh khủng. Phải kèm thêm rất nhiều Design khác đi kèm để tăng performance. Tầng Domain ko kèm DB ở bên trong, nên hầu như mọi thứ đều làm trên memory. Trước đây cũng vì code kiểu này mà product mình từng làm chết trên production vì host trên con server lởm (share resource VPS)
4/ DDD + Clean code + CQRS thực sự RẤT CỒNG KỀNHRẤT NHIỀU BOILERPLATE code. Cụ thể là boilerplate ở CQRS.
Flow Cơ bản của mình là: API Controller -> Command -> Command Handler -> Repository -> UnitOfWork(Db)
5/ Phần test, mình không thích xài Mock Test lắm, nhưng khá là đồng tình là có thể setup và móc thẳng 1 DB test(in memory db)
 
đây là pet project mình đang tạm setup.
View attachment 2105121

Gồm có: DDD + CQRS + Clean Architecture (C#)
Có vài điều mình vẫn còn đang khá lăn tăn.
1/ DDD khá cồng kềnh, mapping giữa internal properties(getters, setters bên Java) bằng constructor --> constructor bị phình to khá nhiều nếu entity có nhiều properties
2/ để gọi là clean thực sự thì ko hẳn, vì để tháo bớt depedency từ Domain Layer thì lại dùng interface để "cheat" dependency diagram.
3/Khi thử sử dụng DDD, khi load cả AggregateRoot (nhiều entities) lên memory thì kinh khủng. Phải kèm thêm rất nhiều Design khác đi kèm để tăng performance. Tầng Domain ko kèm DB ở bên trong, nên hầu như mọi thứ đều làm trên memory. Trước đây cũng vì code kiểu này mà product mình từng làm chết trên production vì host trên con server lởm (share resource VPS)
4/ DDD + Clean code + CQRS thực sự RẤT CỒNG KỀNHRẤT NHIỀU BOILERPLATE code. Cụ thể là boilerplate ở CQRS.
Flow Cơ bản của mình là: API Controller -> Command -> Command Handler -> Repository -> UnitOfWork(Db)
5/ Phần test, mình không thích xài Mock Test lắm, nhưng khá là đồng tình là có thể setup và móc thẳng 1 DB test(in memory db)
Thường thì nếu như domain object to quá thì fence nên nghĩ tới việc tìm cách chia nhỏ nó ra là được.
Còn từ Api Controller -> Command Handler -> Repo thì fence ko phải implement tầng service như bình thường thì mình ko nghĩ là phải boilerplate nhiều gì đâu. Xài Cqrs không thôi với flow như fence kể thì ổn mà.
 
Thường thì nếu như domain object to quá thì fence nên nghĩ tới việc tìm cách chia nhỏ nó ra là được.
Còn từ Api Controller -> Command Handler -> Repo thì fence ko phải implement tầng service như bình thường thì mình ko nghĩ là phải boilerplate nhiều gì đâu. Xài Cqrs không thôi với flow như fence kể thì ổn mà.
mình còn tính làm thêm phần event sourcing nữa. Đã setup thử cho 1 entity, cũng khá ổn, mà để stress test thử xem coi chịu đc nhiệt ko. Ko đc thì phải coi lại phần design :D.

Tựu chung lại là app CRUD ko nên làm DDD, xài clean arch + CQRS là ổn.
 
Đợt tôi có xem video này quan điểm khá hay về clean code. Chung quy lại là tùy dự án mà áp dụng thôi, code tốt và dễ maintain chưa chắc cần follow clean code :angry:. Dev hay bị cuốn vào Overengineering, nhiều khi một cái service rất đơn giản vài ngàn user, mà nhồi một lố architect + công nghệ vô :canny:
 
Đợt tôi có xem video này quan điểm khá hay về clean code. Chung quy lại là tùy dự án mà áp dụng thôi, code tốt và dễ maintain chưa chắc cần follow clean code :angry:. Dev hay bị cuốn vào Overengineering, nhiều khi một cái service rất đơn giản vài ngàn user, mà nhồi một lố architect + công nghệ vô :canny:
đúng. Để áp dụng DDD đúng như Martin Flower hay như trong sách thì nó rất là bí bách, vì quá nhiều layer. Cứ mỗi layer thì phải làm data mapping -> rất dễ bị convert data error hoặc bị duplicate data model.

Clean code có nghĩa là clean ở mức readable, chứ ko có nghĩa là clean code là best performance code.

Cụ thể nếu như post trước của mình, nếu làm task bulk import, thì connect thẳng db và dump data vào db sẽ bao nhanh hơn là clean code gọi qua CQRS để insert từng record.
 
mình còn tính làm thêm phần event sourcing nữa. Đã setup thử cho 1 entity, cũng khá ổn, mà để stress test thử xem coi chịu đc nhiệt ko. Ko đc thì phải coi lại phần design :D.

Tựu chung lại là app CRUD ko nên làm DDD, xài clean arch + CQRS là ổn.
Cái mapping thì đúng là khá cồng kềnh nhưng mà nên follow như thế. Mỗi layers nên có 1 mapping riêng để tránh bug, nhiều thằng dev nó get set loạn xạ cả lên mà ko qui định rõ ràng thì nhiều lúc sẽ dính reference change + việc set nó dupplicate rất nhiều nơi.
Nên thằng domain object sẽ chỉ có private set thôi.
Fence code nhiều thì thấy nó ổn :D 1 phần nữa thường fence sẽ thiếu đó là phần integration với các services khác qua rest hoặc qua message queue thường thì sẽ đặt ở sau tầng repository. Và tầng này cũng phải có data object riêng vì liên quan nhiều tới external communication.
Cái mình bực nhất là các mapper thôi, kinh nghiệm của mình thì nên né những cái như AutoMapper ra và tuyệt đối ko dùng. Vừa tốn thời gian học library code vừa khó clean.
 
Cái mapping thì đúng là khá cồng kềnh nhưng mà nên follow như thế. Mỗi layers nên có 1 mapping riêng để tránh bug, nhiều thằng dev nó get set loạn xạ cả lên mà ko qui định rõ ràng thì nhiều lúc sẽ dính reference change + việc set nó dupplicate rất nhiều nơi.
Nên thằng domain object sẽ chỉ có private set thôi.
Fence code nhiều thì thấy nó ổn :D 1 phần nữa thường fence sẽ thiếu đó là phần integration với các services khác qua rest hoặc qua message queue thường thì sẽ đặt ở sau tầng repository. Và tầng này cũng phải có data object riêng vì liên quan nhiều tới external communication.
Cái mình bực nhất là các mapper thôi, kinh nghiệm của mình thì nên né những cái như AutoMapper ra và tuyệt đối ko dùng. Vừa tốn thời gian học library code vừa khó clean.
cứ qua mỗi 1 mapper là chắc chắn sẽ có bug nếu map sai. Vì thế phải thêm 1 tầng test nữa, khá rối rắm. Mình cứ đơn giản, đã thêm service layer và đã bỏ.

mình cũng ko dùng Mapper lib nào cả. Tự map tay thôi vì kinh nghiệm trước có làm 1 dự án nó map projection bị sai. Nên từ đó map tay sẽ tốt hơn.

Mình cũng code khá nhiều nên cũng muốn làm gì đó đơn giản là đc, vừa đủ tầng cho clean, vừa ko quá cồng kềnh.
 
cứ qua mỗi 1 mapper là chắc chắn sẽ có bug nếu map sai. Vì thế phải thêm 1 tầng test nữa, khá rối rắm. Mình cứ đơn giản, đã thêm service layer và đã bỏ.

mình cũng ko dùng Mapper lib nào cả. Tự map tay thôi vì kinh nghiệm trước có làm 1 dự án nó map projection bị sai. Nên từ đó map tay sẽ tốt hơn.

Mình cũng code khá nhiều nên cũng muốn làm gì đó đơn giản là đc, vừa đủ tầng cho clean, vừa ko quá cồng kềnh.
Cẩn thận thôi, code nhiều thì sẽ ko có cái bug nào cả. Xưa dính mấy bug về reference mới khó chứ bug về việc mapping liếc mắt cái nhìn ra ngay, sửa đơn giản :D
 
Nhiều khi bị lỗi mapping nhưng không phải ở service throw exception mà là những service trước map data sai nữa. Tụi nó không throw exception, phải trace lòi mắt :mad:
 
đây là pet project mình đang tạm setup.
View attachment 2105121

Gồm có: DDD + CQRS + Clean Architecture (C#)
Có vài điều mình vẫn còn đang khá lăn tăn.
1/ DDD khá cồng kềnh, mapping giữa internal properties(getters, setters bên Java) bằng constructor --> constructor bị phình to khá nhiều nếu entity có nhiều properties
2/ để gọi là clean thực sự thì ko hẳn, vì để tháo bớt depedency từ Domain Layer thì lại dùng interface để "cheat" dependency diagram.
3/Khi thử sử dụng DDD, khi load cả AggregateRoot (nhiều entities) lên memory thì kinh khủng. Phải kèm thêm rất nhiều Design khác đi kèm để tăng performance. Tầng Domain ko kèm DB ở bên trong, nên hầu như mọi thứ đều làm trên memory. Trước đây cũng vì code kiểu này mà product mình từng làm chết trên production vì host trên con server lởm (share resource VPS)
4/ DDD + Clean code + CQRS thực sự RẤT CỒNG KỀNHRẤT NHIỀU BOILERPLATE code. Cụ thể là boilerplate ở CQRS.
Flow Cơ bản của mình là: API Controller -> Command -> Command Handler -> Repository -> UnitOfWork(Db)
5/ Phần test, mình không thích xài Mock Test lắm, nhưng khá là đồng tình là có thể setup và móc thẳng 1 DB test(in memory db)
1. b làm cách nào thì nếu đã clean code, mỗi component sẽ đều có prop riêng, chứ ai lại đi dùng ouput của 1 component khác.
2. Domain layer exposes các behavior của nó cho các layer khác (= aggregate root). b k thể tháo bớt vì business nó define thế.
3. case này mình sẽ k load cái collection đó lên. các behavior lên collection đó sẽ chuyển về event -> projection
5. code sẽ luôn có ít nhất unit và intergration test. unit thì phải mock r chạy sao đc
 
Back
Top