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

  • Người tạo chủ đề Người tạo chủ đề soibac123bk
  • Ngày bắt đầu Ngày bắt đầu
- Mình có đọc cuốn Clean Architecture có tác giả Robert Martin, lúc mới đọc thì cảm thấy như tìm được chân lý vậy nhưng sau khi áp dung nó vào trong công việc thì thấy thưc sự có nhiều vấn đề, cụ thể như sau:

  • Khối lượng code sẽ phình ra rất nhiều, và tồn tại rất nhiều boilerplate => code rất chán.
ko clean còn chán hơn, như t đang phải sửa code trong 1 file 60k dòng
  • Trong giai đoạn đầu của project, khi mà requirements thay đổi liên tục thì để sửa code được implement theo clean architecture rất tốn thời gian cụ thể: phải sửa entities, repository, business logic ...
Lạ nhỉ, trừ khi sửa ERD còn đâu có phải sửa mấy cái đấy đâu nhỉ, còn BL thì clean mới dễ sửa chứ, giả sử t code bẩn cho luôn BL vào view/model thì thằng sửa khóc thét
  • Hầu hết chúng ta đang sử dụng framework và hầu hết những framework này đều không tuân thủ Clean Architecture, nên để áp dụng nó mình phải bỏ những phần được framework hỗ trợ, và chọn cách đi lòng vòng hơn để tuân thủ SOLID. Đôi lúc thấy bản thân mình như chế tạo lại cái bánh xe vậy.
SOLID để tăng năng suất, b máy móc đến nỗi tự làm giảm năng suất vì SOLID thì sai rồi
Đó là những khó khăn mình đang gặp phải khi áp dụng clean architecture vào các dự án hiện tại của mình. Để áp dụng được thì không khó, nhưng thực sự thấy có quá nhiều vấn đề. Mong các cao nhân trên đây chia sẻ về kiến trúc này và chia sẻ thêm về kiến trúc code trong các dự án hiện tại của mọi người.
 
del mẹ, nãy giờ tôi luôn nói
tập trung function tối ưu sau :D
mà thôi mấy ông trình cao quá, tôi trình còi, ếch ngồi đáy giếng, nên tôi tập trung kiếm tiền, để dành phần code đẹp cho mấy ông :D
tôi nói rồi, mấy ông luôn luôn nếu... thì...., luôn luôn muốn phức tạp mấy thứ ko cần thiết, luôn luôn suy nghĩ mấy cái viễn tưởng :D trình độ dev nó khác nhau ở đó, pro thì biết cách biến phức tạp thành đơn giản, còn newbie thì biết cách biến đơn giản thành phức tạp :D
thế nhé :D
dAlvIEN.gif


Tôi hiểu ý ông mà, chính bản thân tôi cũng đang làm y chang ông đây, cũng solo, cũng tự design, chả clean arch gì cả. Nhưng ở đời, cái gì tồn tại thì đều có lý do của nó.

Tôi được cái hay tò mò nên cũng muốn xem tại sao nó lại xuất hiện, tại sao tôi ko xài bao giờ, mà nhiều chỗ người ta vẫn xài, mấy anh trên này cũng nói là đang xài? Chắc phải có bí ẩn nào đó.
Nếu ông ko giúp tôi giải đáp được thì thôi vậy.
krWMlnL.gif
 
Ý thím là phải dùng orm thay vì draw query ah
[Tạm thời ignore ông 2007 :LOL:]
Không phải.

1 là Web là entry point, nếu mỗi lần vào website, bạn query trực tiếp vào database thì rất dễ bị treo khi dính DDOS. Mình chỉ cần dùng JMeter query 100 thread/second đến entry point là database có khả năng bị lock. Thường có mấy cách để giải quyết vấn đề này, 1 là dùng rate limiter trên API Gateway, 2 là implement rate limiter trên chính web controller, 3 là caching.

2 là bạn mất đi khả năng enrich user data. Ví dụ giờ mình muốn query thêm user preference ở 1 table khác. Với cách hiện tại thì bạn phải viết thêm 1 query khác trong Web Controller, query đến table user preference, rồi join lại trong web controller và return. Busines logic trong controller sẽ trở nên rất lớn, trong khi nó nên chỉ có nhiệm vụ là gọi các service có liên quan và trả lại response. Viết Unit Test cũng rất đơn giản.

3 là reusability, nếu 1 web controller khác muốn query user info y hệt, thì bạn phải copy code từ controller này, copy qua controller khác => dẫn đến khó maintain code. Hoặc bạn gọi controller này từ controller khác => lâu dài dẫn đến khả năng cyclic dependencies (Controller 1 gọi Controller 2, Controller 2 gọi Controller 3 rồi Controller 3 gọi Controller 1)

Còn nếu như bạn đẩy database task xuống 1, 2 layer nữa như service layer thì các controller gọi service layer là xong, Unit test 1 lần bên Service Layer, ko bị cyclic dependencies. Ngoài ra nếu implement caching trên service layer sẽ tốt hơn là trên controller (vì share được giữa các service). Hoặc dùng caching service riêng như Memcached, Redis tuỳ project thì chỉ cần call ở Service layer là được, thay vì phải call nhiều lần ở nhiều Controller khác nhau.

Đại khái là vậy, tuỳ vào project sẽ có rất nhiều cách làm khác nhau. Nhưng access trực tiếp database từ web controller sẽ xoá bỏ hết các khả năng này, càng làm code sẽ càng rối :LOL:.
 
Đại khái là vậy, tuỳ vào project sẽ có rất nhiều cách làm khác nhau. Nhưng access trực tiếp database từ web controller sẽ xoá bỏ hết các khả năng này, càng làm code sẽ càng rối :LOL:.
Thật ra tôi cũng toàn access db từ controller.
sZKNVVE.png


Được cái toàn code pet project vớ vẩn nên mấy khả năng trên chưa bao giờ gặp.
Hị hị.
krWMlnL.gif
 
[Tạm thời ignore ông 2007 :LOL:]
Không phải.

1 là Web là entry point, nếu mỗi lần vào website, bạn query trực tiếp vào database thì rất dễ bị treo khi dính DDOS. Mình chỉ cần dùng JMeter query 100 thread/second đến entry point là database có khả năng bị lock. Thường có mấy cách để giải quyết vấn đề này, 1 là dùng rate limiter trên API Gateway, 2 là implement rate limiter trên chính web controller, 3 là caching.

2 là bạn mất đi khả năng enrich user data. Ví dụ giờ mình muốn query thêm user preference ở 1 table khác. Với cách hiện tại thì bạn phải viết thêm 1 query khác trong Web Controller, query đến table user preference, rồi join lại trong web controller và return. Busines logic trong controller sẽ trở nên rất lớn, trong khi nó nên chỉ có nhiệm vụ là gọi các service có liên quan và trả lại response. Viết Unit Test cũng rất đơn giản.

3 là reusability, nếu 1 web controller khác muốn query user info y hệt, thì bạn phải copy code từ controller này, copy qua controller khác => dẫn đến khó maintain code. Hoặc bạn gọi controller này từ controller khác => lâu dài dẫn đến khả năng cyclic dependencies (Controller 1 gọi Controller 2, Controller 2 gọi Controller 3 rồi Controller 3 gọi Controller 1)

Còn nếu như bạn đẩy database task xuống 1, 2 layer nữa như service layer thì các controller gọi service layer là xong, Unit test 1 lần bên Service Layer, ko bị cyclic dependencies. Ngoài ra nếu implement caching trên service layer sẽ tốt hơn là trên controller (vì share được giữa các service). Hoặc dùng caching service riêng như Memcached, Redis tuỳ project thì chỉ cần call ở Service layer là được, thay vì phải call nhiều lần ở nhiều Controller khác nhau.

Đại khái là vậy, tuỳ vào project sẽ có rất nhiều cách làm khác nhau. Nhưng access trực tiếp database từ web controller sẽ xoá bỏ hết các khả năng này, càng làm code sẽ càng rối :LOL:.
Bác có thể cho em biết nếu làm một project thông thường, không qúa gắt cũng k quá lỏng về deadline thì bác sẽ chọn để chia ra thành những layer nào được không?
 
Tôi thấy ông rewind đề cập đúng rồi đấy. Vấn đề ở đây là context, mà context phải rõ ràng, chỉ một câu của ông "bám sát vào chất lượng sản phầm, vào hiệu suất" là chưa đủ.

Nhiều khi phải rõ ràng cả team size, trình độ, ngôn ngữ, rồi số lượng tính năng, vòng đời của sản phẩm, yêu cầu của client, rồi còn dựa vào code base cũ (nếu có) ... càng cụ thể, càng chi tiết thì tranh cãi mới đúng được. Còn ko thì giống như ông nói xuôi, bà nói ngược, như mấy bà hàng cá nói cho át tiếng người khác là thắng, vậy ko thú vị.

Tôi nghĩ, thay vì chê mấy anh ở đây sáo rỗng, sao ông ko đưa ý kiến xem, khi nào thì cần clean arch?
Tôi thấy lúc nào cũng cần clean hết. Người ta chưa clean vì người ta chưa thể clean thôi. Nhìn chung, có thể nói là do tầm nhìn của người leader và do requirement của product.

1. Ví dụ. Ko clean thì làm cách nào product lớn nhưng grab có thể launch ở nhiều thị trường như thế. Grab có những template gen code service để giải quyết vấn đề của họ.
Tuy nhiên team startup học theo cái code gen của họ thì chê.

2. Team đông, người ra người vào nhiều, nhiều repo, phức tạp từ việc setup. -> Cần clean hơn để giảm thời gian người mới join team và làm task.
Chuẩn để hạn chế sai lầm của dev, dev hư lắm. Giấu bug, giấu dốt, lười làm, ẩu tả. Clean cũng là một cách bắt họ làm theo những điều đúng đắn đã đc kiểm nghiêm, loại trừ những cách code ẩu tả, tà đạo của dev. :)
 
Sửa lần cuối:
Thật ra tôi cũng toàn access db từ controller.
sZKNVVE.png


Được cái toàn code pet project vớ vẩn nên mấy khả năng trên chưa bao giờ gặp.
Hị hị.
krWMlnL.gif
ban đầu triển khai viết thế cx đc thôi, như tôi thì tuỳ fw nữa, trc sau gì tôi cx move về service, nên mấy fw dùng DI thì tôi move luôn từ đầu cho khoẻ, còn như rails/laravel access static method nên viết trong controller lúc đầu, xong logic r move về service sau
 
Tôi thấy lúc nào cũng cần clean hết. Người ta chưa clean vì người ta chưa thể clean thôi. Nhìn chung, có thể nói là do tầm nhìn của người leader và do requirement của product.

1. Ví dụ. Ko clean thì làm cách nào product lớn nhưng grab có thể launch ở nhiều thị trường như thế. Grab có những template gen code service để giải quyết vấn đề của họ.
Tuy nhiên team startup học theo cái code gen của họ thì chê.

2. Team đông, người ra người vào nhiều, nhiều repo, phức tạp từ việc setup. -> Cần clean hơn để giảm thời gian người mới join team và làm task.
Chuẩn để hạn chế sai lầm của dev, dev hư lắm. Giấu bug, giấu dốt, lười làm, ẩu tả. Clean cũng là một cách bắt họ làm theo những điều đúng đắn đã đc kiểm nghiêm, loại trừ những cách code ẩu tả, tà đạo của dev. :)
clean code cũng có mức độ clean, nên cứ làm tốt nhất có thể ở thời điểm làm là tốt nhất, cái gì có thể clean mà ko tốn effort thì nên làm ngay từ đầu, chứ nó cx ko có cái sau này refactor
 
Tôi thấy lúc nào cũng cần clean hết. Người ta chưa clean vì người ta chưa thể clean thôi. Nhìn chung, có thể nói là do tầm nhìn của người leader và do requirement của product.

1. Ví dụ. Ko clean thì làm cách nào product lớn nhưng grab có thể launch ở nhiều thị trường như thế. Grab có những template gen code service để giải quyết vấn đề của họ.
Tuy nhiên team startup học theo cái code gen của họ thì chê.

2. Team đông, người ra người vào nhiều, nhiều repo, phức tạp từ việc setup. -> Cần clean hơn để giảm thời gian người mới join team và làm task.
Chuẩn để hạn chế sai lầm của dev, dev hư lắm. Giấu bug, giấu dốt, lười làm, ẩu tả. Clean cũng là một cách bắt họ làm theo những điều đúng đắn đã đc kiểm nghiêm, loại trừ những cách code ẩu tả, tà đạo của dev. :)
À, khi đề cập đến clean arch, thì tôi nghĩ phải nói rõ xem clean đến mức độ nào. Nhiều project chia vài ba layer là quá đủ rồi, nhưng có những project lại phải phức tạp hơn.
 
Bác có thể cho em biết nếu làm một project thông thường, không qúa gắt cũng k quá lỏng về deadline thì bác sẽ chọn để chia ra thành những layer nào được không?
mình lấy ví dụ trong Java nhé (giờ toàn code Java). Bên mình giờ code thế này:

Controller > Service > Data Service > Repository

Trong Controller dùng Dto với Mapper (Mapstruct) package level (interface xxxMapper, class xxxDto, ko dùng public class Dto, public interface xxxMapper)
Trong Service dùng package level Mapper với public Domain Object (đây là public class duy nhất trong đống Dto, Domain, Database Model Entity)
Data Service sẽ có default package level Mapper với default package level Database Model (không dùng public Database Entity)

Các layer chỉ được gọi layer bên phải, không được gọi ngược lại hay ngang hàng để tránh cyclic dependencies.

Ngoài ra nếu mình cần 2 kết quả của 2 Service thì trong package của Controller, mình tạo thêm 1 package level ServiceManager, gọi 2 service khác rồi trả lại kết quả cho Controller:

Controller > Service Manager > Service > Data Service > Repository

Cách làm này gần giống với Clean Architecture, sửa layer bất kì sẽ ko ảnh hưởng đến layer bên phải. Nhưng có thể dùng trong cùng 1 module (ko nhất thiết phải chia ra nhiều module như clean architecture).

Bạn nào có ý kiến khác thì reply để mình tham khảo thêm :LOL:
 
clean code cũng có mức độ clean, nên cứ làm tốt nhất có thể ở thời điểm làm là tốt nhất, cái gì có thể clean mà ko tốn effort thì nên làm ngay từ đầu, chứ nó cx ko có cái sau này refactor
À, khi đề cập đến clean arch, thì tôi nghĩ phải nói rõ xem clean đến mức độ nào. Nhiều project chia vài ba layer là quá đủ rồi, nhưng có những project lại phải phức tạp hơn.
Thì đó. Vẫn là cần phải có cái tư duy clean trong đầu.

Vì sao: Đơn giản codebase xịn trên thế giới có cái nào không clean? Trình architechture không hay đọc code à? Đọc code hay thì sẽ thích code hay.
Sẽ rất phi lý nếu độ senior của 1 developer không tuyến tính với tính clean trong code của họ.

Còn clean đến mức nào thì bao nhiêu ngôn ngữ bao nhiêu framework, còn nhiều cách deploy nữa. Không phán được.
Nếu trả lời cho câu clean có giúp chúng ta tốt hơn thì nó cũng như là đi học đại học có giúp chúng ta đi làm tốt hơn.
Thật khó nói. :)
 
mình lấy ví dụ trong Java nhé (giờ toàn code Java). Bên mình giờ code thế này:

Controller > Service > Data Service > Repository

Trong Controller dùng Dto với Mapper (Mapstruct) package level (interface xxxMapper, class xxxDto, ko dùng public class Dto, public interface xxxMapper)
Trong Service dùng package level Mapper với public Domain Object (đây là public class duy nhất trong đống Dto, Domain, Database Model Entity)
Data Service sẽ có default package level Mapper với default package level Database Model (không dùng public Database Entity)

Các layer chỉ được gọi layer bên phải, không được gọi ngược lại hay ngang hàng để tránh cyclic dependencies.

Ngoài ra nếu mình cần 2 kết quả của 2 Service thì trong package của Controller, mình tạo thêm 1 package level ServiceManager, gọi 2 service khác rồi trả lại kết quả cho Controller:

Controller > Service Manager > Service > Data Service > Repository

Cách làm này gần giống với Clean Architecture, sửa layer bất kì sẽ ko ảnh hưởng đến layer bên phải. Nhưng có thể dùng trong cùng 1 module (ko nhất thiết phải chia ra nhiều module như clean architecture).

Bạn nào có ý kiến khác thì reply để mình tham khảo thêm :LOL:
Service manager chủ mang tính logic thôi nhỉ. Nó không cần cũng ko sao.
 
Thì đó. Vẫn là cần phải có cái tư duy clean trong đầu.

Vì sao: Đơn giản codebase xịn trên thế giới có cái nào không clean? Trình architechture không hay đọc code à? Đọc code hay thì sẽ thích code hay.
Sẽ rất phi lý nếu độ senior của 1 developer không tuyến tính với tính clean trong code của họ.

Còn clean đến mức nào thì bao nhiêu ngôn ngữ bao nhiêu framework, còn nhiều cách deploy nữa. Không phán được.
Nếu trả lời cho câu clean có giúp chúng ta tốt hơn thì nó cũng như là đi học đại học có giúp chúng ta đi làm tốt hơn.
Thật khó nói. :)
Tôi đồ rằng ông rồng cũng phải clean thôi, nhưng là clean theo cách của ổng.
Thật ra nói clean arch cũng trừu tượng vãi cớt, có rất nhiều cách hiểu, rất nhiều cách áp dụng, nên thành ra dễ cãi nhau nếu ko clear được context.
 
Clean code chủ yếu là principle, convention đặt ra để code dễ đọc, hiểu, bảo trì
Clean Architecture thừa hưởng tư tưởng này nhưng để implement thì cũng có một số bất cập do over engineering có thể kể đến là:
- Chia tách quá nhiều lớp => Dẫn đến các quy định code quá nhiều, hướng dẫn dev dài như sớ, dev không biết vào đâu để sửa chức năng mong muốn. Code bị phức tạp hóa và không thực sử giải quyết vấn đề
- Quá phụ thuộc vào abstract, đôi khi abtract gây ra thay vì giải quyết vấn đề .
- Code không thực sự "clean". Code ở service cũng xấu như ở lớp controller, khác mỗi cái là bị abtract đi.
Quan trọng là tư tưởng clean code chứ đừng cứng nhắc, dập khuôn. Cá nhân tôi đang tìm hiểu thấy vertical slice architecture khá hay, trong mỗi slice cũng có thể làm onion/clean arch cũng đc tùy team.
 
Clean code chủ yếu là principle, convention đặt ra để code dễ đọc, hiểu, bảo trì
Clean Architecture thừa hưởng tư tưởng này nhưng để implement thì cũng có một số bất cập do over engineering có thể kể đến là:
- Chia tách quá nhiều lớp => Dẫn đến các quy định code quá nhiều, hướng dẫn dev dài như sớ, dev không biết vào đâu để sửa chức năng mong muốn. Code bị phức tạp hóa và không thực sử giải quyết vấn đề
- Quá phụ thuộc vào abstract, đôi khi abtract gây ra thay vì giải quyết vấn đề .
- Code không thực sự "clean". Code ở service cũng xấu như ở lớp controller, khác mỗi cái là bị abtract đi.
Quan trọng là tư tưởng clean code chứ đừng cứng nhắc, dập khuôn. Cá nhân tôi đang tìm hiểu thấy vertical slice architecture khá hay, trong mỗi slice cũng có thể làm onion/clean arch cũng đc tùy team.
Concept này khá hay. Xuống dưới database model thì có dùng ORM được không? Vì bình thường chỉ có 1 entity map với 1 database table, mà như thế là thành shared entity :-? Nếu dùng manual query (như mybatis) thì ko có vấn đề.
 
Clean code chủ yếu là principle, convention đặt ra để code dễ đọc, hiểu, bảo trì
Clean Architecture thừa hưởng tư tưởng này nhưng để implement thì cũng có một số bất cập do over engineering có thể kể đến là:
- Chia tách quá nhiều lớp => Dẫn đến các quy định code quá nhiều, hướng dẫn dev dài như sớ, dev không biết vào đâu để sửa chức năng mong muốn. Code bị phức tạp hóa và không thực sử giải quyết vấn đề
- Quá phụ thuộc vào abstract, đôi khi abtract gây ra thay vì giải quyết vấn đề .
- Code không thực sự "clean". Code ở service cũng xấu như ở lớp controller, khác mỗi cái là bị abtract đi.
Quan trọng là tư tưởng clean code chứ đừng cứng nhắc, dập khuôn. Cá nhân tôi đang tìm hiểu thấy vertical slice architecture khá hay, trong mỗi slice cũng có thể làm onion/clean arch cũng đc tùy team.
Mình thấy như architect hiện giờ làm mới mà dự án lớn thì xài microservices, 1 team sở hữu 1 hoặc vài domain là ổn. Thường chia ra domains như vậy thì sources sẽ không lớn. Xong rồi ở các microservices xài 3 layers hoặc thêm Cqrs là ok. Cũng ko cần phải over engineering quá bằng cái clean architect này làm gì.
Mà tách ra thành microservices lại có nhiều các concept khác về system architecture phải lo. Cái gì cũng có trade off cả thôi :D

via theNEXTvoz for iPhone
 
Concept này khá hay. Xuống dưới database model thì có dùng ORM được không? Vì bình thường chỉ có 1 entity map với 1 database table, mà như thế là thành shared entity :-? Nếu dùng manual query (như mybatis) thì ko có vấn đề.
1 slice hoàn toàn có thể dùng micro ORM hay full ORM hoặc dùng external API, sẽ có những đoạn code bị lặp nhưng bù lại sẽ có slice feature độc lập và ít phụ thuộc vào nhau thì tôi thấy cũg được
 
1 slice hoàn toàn có thể dùng micro ORM hay full ORM hoặc dùng external API, sẽ có những đoạn code bị lặp nhưng bù lại sẽ có slice feature độc lập và ít phụ thuộc vào nhau thì tôi thấy cũg được
Ah ok, mình quên mất có multi mapping. Cái này micro ORM hay full ORM đều được. :LOL:
 

Thống kê chủ đề

Ngày tạo
soibac123bk,
Người trả lời cuối
CSharpCorner,
Trả lời
253
Lượt xem
50.376
Quay lại
Lên đầu trang