kiến thức Chia sẻ kinh nghiệm về Repository pattern

  • Người tạo chủ đề Người tạo chủ đề hoctrokha
  • Ngày bắt đầu Ngày bắt đầu
Tôi đọc hết cả #1 thì thú thật tôi không hiểu gì hết, quá nhiều từ viết tắt, cũng không đặt trong trường hợp nào rõ ràng cụ thể, anh chỉ đang bàn về 1 cái pattern thôi? Hay anh muốn bàn về cái pattern đó sau khi đã được hiện thực hoá trên 1 cái môi trường nào đó, trên 1 ngôn ngữ lập trình cụ thể nào? Người tamuốn tranh luận cũng không biết bắt nguồn từ đâu
 
Có chuyển cũng chỉ chuyển từng phần nào đó cần thiết.

Ở đây có bạn nào “may mắn” được/bị làm việc với các hệ thống “có vẻ” là microservices sẽ hiểu cảm giác khổ sở vê lờ khi biz nó đòi hỏi một cái feature gì đó mà cái “microservices “ hiện tại nó không đáp ứng được.

Khi đó lại phải ngồi nghĩ cách cheating, hacking, adhoc… blabla để workaround được cái yêu cầu. Lúc này chỉ muốn đập cmn hết đi làm monolith.

Cái này là hệ quả của việc triển khai “microservices” theo ý chí của tech mà không xét đến biz.

+1 cho bác

Đang làm với 1 hệ thống design ban đầu là module mono. Nhưng sếp mới vào áp dụng giải pháp micro service. Cuối cùng thành 1 mớ hỗ độn, trong khi người cầm key chính maintain vẫn là mình :sad:

Cay hơn là sếp đưa ra giải pháp block vài phút, để 2 service nói chuyện với nhau theo kiểu settimeout. Max ping cho 1 giải pháp bét sô nu sừn.
 
+1 cho bác

Đang làm với 1 hệ thống design ban đầu là module mono. Nhưng sếp mới vào áp dụng giải pháp micro service. Cuối cùng thành 1 mớ hỗ độn, trong khi người cầm key chính maintain vẫn là mình :sad:

Cay hơn là sếp đưa ra giải pháp block vài phút, để 2 service nói chuyện với nhau theo kiểu settimeout. Max ping cho 1 giải pháp bét sô nu sừn.

Sếp mới bác Master Microservices đó bác. Chắc không biết Monolithic là gì ấy bác.
 
+1 cho bác

Đang làm với 1 hệ thống design ban đầu là module mono. Nhưng sếp mới vào áp dụng giải pháp micro service. Cuối cùng thành 1 mớ hỗ độn, trong khi người cầm key chính maintain vẫn là mình :sad:

Cay hơn là sếp đưa ra giải pháp block vài phút, để 2 service nói chuyện với nhau theo kiểu settimeout. Max ping cho 1 giải pháp bét sô nu sừn.
Làm việc với microservices cũng đủ lâu để rút dc nhiều kinh nghiệm đau thương. Giờ ông nào mà cứ đòi microservices là cứ phải debate chán chê, chứng minh value mang lại khi áp dụng microservices mới làm. :shame:

https://scs-architecture.org/ -> Bây giờ mới nghiệm ra cái này mới là chân lý. :shame:
 
Làm việc với microservices cũng đủ lâu để rút dc nhiều kinh nghiệm đau thương. Giờ ông nào mà cứ đòi microservices là cứ phải debate chán chê, chứng minh value mang lại khi áp dụng microservices mới làm. :shame:

https://scs-architecture.org/ -> Bây giờ mới nghiệm ra cái này mới là chân lý. :shame:

Bác ơi vậy có nên học Microservices không ạ. Em biết về Git với Docker + Kubernetes + AWS + Google Cloud là đủ chưa ạ.
 
Bác ơi vậy có nên học Microservices không ạ. Em biết về Git với Docker + Kubernetes + AWS + Google Cloud là đủ chưa ạ.
Microservices không sai, vấn đề nằm ở người áp dụng cho nên cứ học tẹt đi.
Git, Docker, K8s... nó là công cụ để giúp bạn triển khai microservices dễ hơn.
AWS, GCP có nhiều managed services giúp bạn nhẹ gánh hơn nữa. Học càng nhiều càng tốt.

Mình giờ dùng IaaS là chính chứ AWS, GCP chả mấy khi dùng nữa do nhu cầu ko tới. Dùng IaaS của Linode/Vultr rẻ hơn nhiều.
 
Bác nào giải thích rõ giúp em cái aggregate là gì trong ddd không? Nếu có ví dụ càng tốt ạ.

via theNEXTvoz for iPhone
Aggregate là một cụm các Entity/Value Object liên quan đến nhau trong 1 tính năng nhất định.
Ở đây mình sẽ phải giải thích thêm một chút về Entity và Value Object.
Ví dụ bạn trả tiền điện, bạn chỉ cần quan tâm là đúng địa chỉ nhà mình và số tiền phải trả. Đó là cái value BẠN quan tâm. Thế nên khi xử lý thông tin, dev có thể tách nhỏ 2 thông tin này (từ entity gốc là Hóa đơn) tạo thành 1 object nhỏ hơn. Object nhỏ này được gọi là Value Object. Một tập hợp gồm Entity gốc (trong aggregate sẽ được gọi là root) và các Value Object như thế được gọi là một Aggregate.
 
Aggregate là một cụm các Entity/Value Object liên quan đến nhau trong 1 tính năng nhất định.
Ở đây mình sẽ phải giải thích thêm một chút về Entity và Value Object.
Ví dụ bạn trả tiền điện, bạn chỉ cần quan tâm là đúng địa chỉ nhà mình và số tiền phải trả. Đó là cái value BẠN quan tâm. Thế nên khi xử lý thông tin, dev có thể tách nhỏ 2 thông tin này (từ entity gốc là Hóa đơn) tạo thành 1 object nhỏ hơn. Object nhỏ này được gọi là Value Object. Một tập hợp gồm Entity gốc (trong aggregate sẽ được gọi là root) và các Value Object như thế được gọi là một Aggregate.
Tiện cái Hoá Đơn này, bác cho em thấy luôn cái Bounded Context được không?
 
Tiện cái Hoá Đơn này, bác cho em thấy luôn cái Bounded Context được không?
Bounded Context là gì đã. Dịch nghĩa thô ra thì nó là Ngữ cảnh giới hạn. Giới hạn ở đây là gì? Là các ngữ cảnh nó biệt lập với nhau và có thể hoàn toàn không liên quan gì đến nhau luôn mặc dù nó là cùng 1 tính năng.
Tức là cùng 1 cái tính năng Xuất hóa đơn như thế, nhưng với mỗi khách hàng lại có một yêu cầu khác nhau về định dạng thông tin và số lượng thông tin trên tờ hóa đơn. (Ví dụ hóa đơn điện của hộ gia đình chỉ cần có địa chỉ nhà và số tiền phải nộp, nhưng hóa đơn điện của cty lại quan tâm đến cả tổng lượng điện tiêu thụ từng ngày, rồi thay đổi so với kỳ trước đó ...)Thế nên phương án là chúng ta tách mỗi cái "yêu cầu" này thành một ngữ cảnh riêng biệt và phát triển cho nó thành một Microservice. Mỗi khách hàng khi tiếp cận đến cái tính năng "xuất hóa đơn" này là họ sẽ làm việc với cái microservice của riêng họ để nhận về cái mẫu mà họ mong muốn.
 
+1 cho bác

Đang làm với 1 hệ thống design ban đầu là module mono. Nhưng sếp mới vào áp dụng giải pháp micro service. Cuối cùng thành 1 mớ hỗ độn, trong khi người cầm key chính maintain vẫn là mình :sad:

Cay hơn là sếp đưa ra giải pháp block vài phút, để 2 service nói chuyện với nhau theo kiểu settimeout. Max ping cho 1 giải pháp bét sô nu sừn.
Có ý chí thì đạp sếp mà lên thôi fen
 
Làm việc với microservices cũng đủ lâu để rút dc nhiều kinh nghiệm đau thương. Giờ ông nào mà cứ đòi microservices là cứ phải debate chán chê, chứng minh value mang lại khi áp dụng microservices mới làm. :shame:

https://scs-architecture.org/ -> Bây giờ mới nghiệm ra cái này mới là chân lý. :shame:
Bên dự án cũ follow chặt cái này. Cơ bản là nó chịu khó refactor, viết lại nhiều lần. Struts, spring rồi angular 1, angular, war thành jar, on premise lên aws... Tách db liên tục
 
Mọi người đang bị hyped microservices quá rồi. Nó chả phải cái gì thần thần thánh đâu, làm việc với nó từ 2017 đến giờ thì quan điểm của mình luôn là chọn modular monolithic hơn là microservices.
Hãy cố gắng giải quyết vấn đề bằng monolithic, khi nào thấy pros nghiêng hẳn về microservices thì mới nên sử dụng.
úi giờ em mới đọc được comment của bác, chuẩn quá bác ơi, nhiều chỗ em thấy bị thần thánh hóa cái microservice quá rồi, tự nhiên là cho hệ thống nó phực tạp ra, app thì bé tí cũng cả chục cái services call nhau nhặng cả lên, hài thực sự,
 
Microservices không sai, vấn đề nằm ở người áp dụng cho nên cứ học tẹt đi.
Git, Docker, K8s... nó là công cụ để giúp bạn triển khai microservices dễ hơn.
AWS, GCP có nhiều managed services giúp bạn nhẹ gánh hơn nữa. Học càng nhiều càng tốt.

Mình giờ dùng IaaS là chính chứ AWS, GCP chả mấy khi dùng nữa do nhu cầu ko tới. Dùng IaaS của Linode/Vultr rẻ hơn nhiều.


Fallacies của microservices tự mặc định là mọi thứ đều ổn.
Nhưng cả đống này là ổn lòi lìa. Nội tiền phải trả cho đống này cũng tốn kha khá rồi.
  1. The network is reliable;
  2. Latency is zero;
  3. Bandwidth is infinite;
  4. The network is secure;
  5. Topology doesn't change;
  6. There is one administrator;
  7. Transport cost is zero;
  8. The network is homogeneous;
 
Nghe các bạn nói về Microservice mà thấy buồn.
Microservice sinh ra không phải để giải quyết vấn đề của team vài chục người. Nó sinh ra để cho team cỡ 1 - vài trăm người cùng làm việc.
Lý do để làm microservice là independently making progress và promote cho ý tưởng autonomous team.
Đại khái, microservice không giải quyết vấn đề technical, nó giải quyết vấn đề của organization.
Nếu các bạn làm 1 dự án nhỏ, rõ ràng việc thay ORM cũng khá đơn giản, có thể hoàn thành trong 1 -2 tuần bằng cách dùng 2 ORM song song trong 1 monolith, không cần thiết phải micro service làm gì. Còn khi codebase đủ lớn, việc tách micro service là điều khó tránh khỏi.
Và microservice không đơn giản chỉ là tách db + tách code base ra là xong, nó liên quan rất chặt đến Domain Driven Design - thứ mà phần lớn các archtect không hiểu, thành thử mới khiến microservice toạch ngay từ khi mới bắt đầu và trở nên quá sức cồng kềnh sau vài năm.
 
Nghe các bạn nói về Microservice mà thấy buồn.
Microservice sinh ra không phải để giải quyết vấn đề của team vài chục người. Nó sinh ra để cho team cỡ 1 - vài trăm người cùng làm việc.
Lý do để làm microservice là independently making progress và promote cho ý tưởng autonomous team.
Đại khái, microservice không giải quyết vấn đề technical, nó giải quyết vấn đề của organization.
Nếu các bạn làm 1 dự án nhỏ, rõ ràng việc thay ORM cũng khá đơn giản, có thể hoàn thành trong 1 -2 tuần bằng cách dùng 2 ORM song song trong 1 monolith, không cần thiết phải micro service làm gì. Còn khi codebase đủ lớn, việc tách micro service là điều khó tránh khỏi.
Và microservice không đơn giản chỉ là tách db + tách code base ra là xong, nó liên quan rất chặt đến Domain Driven Design - thứ mà phần lớn các archtect không hiểu, thành thử mới khiến microservice toạch ngay từ khi mới bắt đầu và trở nên quá sức cồng kềnh sau vài năm.
Đọc cái này lại thấy buồn cười. Tôi cũng từng gặp kha khá Tech Lead, SA thần thánh Microservice, sơ hở là đòi áp dụng, nhưng ko hiểu được nó dùng để giải quyết vấn đề gì, triển khai ntn, hay thậm chí cũng chả hiểu về DDD. Có ông thì nghĩ project có nhiều service chạy độc lập là microservice, có ông thì cũng tách code tách db, nhưng business logic nhập nhằng tùm lum các service vào nhau, rồi hạ tầng, giải pháp không đáp ứng được cái của nợ trên, team thì có chục ông è cổ ra resolve conflict, rồi lại work-around. Chính bản thân tôi cũng hiểu sai rất lâu, ăn sh*t nhiều quá mới vỡ lẽ ra.
 
Chào mọi người,
Hôm nay lượn lờ thấy có 1 topic nói về repository pattern anh em bàn tán sôi nổi quá:
thảo luận - [Thảo luận] Repository Pattern là cái bullsh*t nhất khi đã có ORM framework? (https://voz.vn/t/thao-luan-repository-pattern-la-cai-bullsh-t-nhat-khi-da-co-orm-framework.490455/)

Khổ cái mình không có nhiều thời gian nên không thể nào follow hết cả 10 trang comment được, nhưng nhìn chung mình thấy vấn đề mọi người đang tranh cãi là:
  • Repository pattern có phải là BS không?
  • Có nên abstract cái ORM không?

Thấy ỏm tỏi quá nên mình viết 1 bài chia sẻ kiến thức của mình về repository pattern, nếu có gì hơi lạc đề hoặc không đúng với những gì mọi người đang thảo luận trong bài kia thì cũng mong mọi người bỏ qua, cứ xem như đây là 1 bài chia sẻ kiến thức là được.

Một xíu về bản thân thì mình hiện đang làm technical architect cho một công ty ở việt nam thôi, không phải làm cho amazone hay google j hết.
Tất cả kiến thức mình có đều từ kinh nghiệm bản thân mà ra thôi.

Ok, trả lời luôn với mọi người là repository pattern vừa BS vừa không hề BS.

Nhưng đầu tiên, Repository pattern dùng để abstract cái ORM đúng là BS.

Vâng nó đúng là BS, lý do nó BS thì mình đoán mọi người cũng đã nói nhiều trong post kia. Mình chỉ muốn nói thêm về trải nghiệm của mình với nó thôi.
Hồi sinh viên chắc ai cũng được thầy cô hướng dẫn mô hình ba lớp, n lớp các thứ, theo lý thuyết thì nó abstract cách lấy data, sau này thay thế tầng đó thì chỉ cần viết lại là xong. Nghe đúng là tuyệt vời và mình vẫn thấy nhiều người làm theo kiểu này, cho dù họ chưa hề có kinh nghiệm về việc thay nguyên tầng DAL trong 1 project lâu năm (chính mình nhiều năm trước cũng đã làm y chang như vậy).
Tất nhiên dần dần những "củ khoai" của tầng DAL cũng lộ diện khiến ai cũng bực mình. Nào là code bị lặp lại, gần như phải cover toàn bộ các API của ORM, rồi về transaction, làm sao để giữ transaction giữa các repository mà vẫn đảm bảo được tính đóng gói, sự abstract của tầng DAL ...

Rồi tiếp đến nếu bạn viết test cho 1 controller thì sao?
Đến bước viết test thì không thể nào các bạn mock nguyên cả tầng DAL được, các bạn phải mock thằng DB bằng in-memory db chứ. Mà in-memory db lại được cung cấp bởi thằng ORM.
OH sh*t, vậy việc abstract ORM của các bạn còn ý nghĩa gì nữa khi test của các bạn bị couple với ORM?
Kinh nghiệm của mình là "Tránh tối đa việc mock thư viện bạn đang dùng". Ví dụ bạn dùng EF thì đừng bao giờ đi mock EF, ở dưới client side bạn dùng axios thì đừng bao giờ mock axios, bởi nó là một phần trong code của các bạn, là một phần của hệ thống.
Trên production bọn nó nói chuyện với nhau, tương tác với nhau, nhưng khi test các bạn quăng 1 thằng fake vào thì khả năng chạy thật bị lỗi là điều dễ hiểu.
Thay vào đó hãy mock các "edge", mock db để ORM nó query, mock các api để trả về data cho axios ...
OK, vậy nếu theo cách tiếp cận đó thì việc thay tầng DAL hoặc thay ORM đúng là thảm cmn họa.
Các bạn sẽ phải viết lại tất cả các test ... coi như toang luôn dự án chứ còn j nữa.

Có thể các bạn sẽ hỏi: "chứ mình muốn đổi DB từ NoSQL qua SQL bởi hiện có những hạn chế, theo chủ thớt nói thì chịu ah?"
Ừ thì đập lại code build lại thôi, đó cũng là lý do microservice ra đời, :D
Cố gắng làm theo microservice để tránh những rủi do kiểu đó nhé, cố gắng đập đi build lại trong vòng 2 tuần.

Vậy khi nào repository pattern không phải BS?
Tất nhiên là khi mới tốt nghiệp repository là thần thánh rồi, :beauty: Đùa thôi.

Trường hợp 1: CQRS

Khi mình bắt đầu thử làm với CQRS thì tự nhiên repository là một thứ được áp dụng vào khá tự nhiên.
Các repository giờ không còn là proxy để các bạn truy vấn các bảng dưới db nữa, nó sẽ thành repository cho các "Aggregate root".
Mục đích của việc dùng repository trong hoàn cảnh này không phải để thay ORM hay là thay tất cả Aggregate root, mà chỉ đơn giản là nó phù hợp thôi.
Nhưng chỉ nên dùng repository cho bên write thôi, còn bên read thì mình dùng thẳng ORM luôn, việc dùng repository để lấy cả Aggregate root ra là điều không cần thiết.
Mình không nghĩ mình cần giải thích thêm vì nếu bạn đã biết CQRS, bạn có lẽ đã hiểu, nếu bạn chưa biết, khả năng cao giải thích cũng vậy.


Trường hợp 2: ORM không hỗ trợ in-memory db

nếu ORM các bạn dùng đủ ngon, có hỗ trợ In-Memory db thì khỏi nói, cứ thế mà viết test thôi. Nhưng nếu ORM của các bạn ko hỗ trợ thì khi test các bạn có 2 option:
  • dùng docker tạo 1 db lên dùng chung cho tất cả các test: cái này tù chày, chậm và dễ sinh ra các flaky test do các test chạy song song
  • dùng repository pattern và mock tất cả các method khi test => max tù chày và độ confident cực thấp

Nếu bạn làm theo TDD thì dùng docker là điều ko thể, ko ai ngồi đợi 1 phút để có kết quả test cho 1 unit test cả.
Bởi vậy bắt buộc phải dùng repository pattern trong trường hợp này, nhưng tốt nhất bạn nên chọn ORM cẩn thận, không bao giờ chọn mấy thằng ko hỗ trợ in-memory db nhé.

Kết luận
Cũng chả có kết luận nào mang tính đao to búa lớn đâu, các bạn nếu không làm CQRS thì mình nghĩ nên dẹp repository pattern đi, chọn ORM cho chuẩn và tập trung viết test cho đàng hoàng.
Code thì lỗi nhoe mà ngồi đó pattern này với chả pattern nọ.
show me da code
 

Thống kê chủ đề

Ngày tạo
hoctrokha,
Người trả lời cuối
GeniVN,
Trả lời
57
Lượt xem
10.458
Quay lại
Lên đầu trang