thảo luận Vấn đề về separate Repository/Service/Controller

  • Người tạo chủ đề Người tạo chủ đề soledad86
  • Ngày bắt đầu Ngày bắt đầu
Có thể do cách trình bày của bạn chưa thuyết phục.
  • Bạn đề nghị làm cách này là nói suông thôi hay có một buổi trình bày bằng slide đàng hoàng? Có viết document hay không?
  • Bạn có thử viết một đoạn code nhỏ nhỏ (càng gần với context của công ty càng tốt) mà người ta đọc vào thấy rõ được sự khác biệt giữa hai cách làm không?

Cứ pick ra một đoạn code hiện tại và viết lại theo cách bạn muốn hướng mọi người. Xong book meeting present giới thiệu cách mới. Nói ngắn gọn đảm bảo người nghe hiểu. Xong cho mọi người ý kiến thảo luận blah blah... Còn làm hết rồi mà vẫn không được thì cũng kệ thôi. :)
Lead chịu chia sẽ lắng nghe thì nó dễ lắm. Giải thích thuyết phục thì mình học hỏi thêm nhiều chứ cũng ko phải chày cối, thần thánh hóa pattern ... ngược lại thì cố gắng adapt, ko thì out thôi.
 
mình nghĩ khi đưa ra 1 solution mới để giải quyết bài toán cho công ty bạn, bạn cần đưa ra được các lý do tại sao cty cần solotion đó.
vd: trong case của bạn. mình nghĩ bạn cần:
1. Chỉ ra được những bất cập do mô hình đang áp dụng gây ra.
2. Chỉ ra những khó khăn mà tương lai có thể gặp phải nếu sử dụng mô hình đó.
3. Chứng tỏ mô hình của bạn giải quyết đc những bất cập đó.
Với mô hình cty bạn đang dùng khá nhiều những bất cập, bạn thử phân tích theo hướng mình nói xem, anh em cty có đồng ý ko.
 
Theo ngu ý của em dùng trực tiếp repo trong controller thì nó là program to implementations rồi.
Ví dụ nếu cần check tồn tại dữ liệu. Đầu tiên viết check bằng query db. Sau đó 1 ngày đẹp trời đọc trên mạng thấy có thằng redis hay thế là sửa bung xoè controller để dùng redis. Lúc chạy thì do vấn đề đồng bộ phải check trong redis nếu ko tồn tại check tiếp trong db lại sửa controller.
Nếu dùng service thì thích implement kiểu gì cũng được. Các class nhiệm vụ rõ ràng.
Thôi con khóc rồi đi thay bỉm đơi.
 
Em làm việc tại công ty X được 3 năm, ae toàn senior.
Tại 1 công ty Y em mới vào, tình hình là em và ae có một số ý kiến bất đồng trong việc phân tách các layers gồm Repository / Service và Controller/Serverless Func

Các bác lâu năm exp cho em hướng xử lý trong case này với.

Sơ sơ tình hình là với vấn đề trên, em sẽ chia ra các layer với reponsibility khác nhau.
1. Repo: sẽ làm việc với SQL và map vào entity. thực hiện các tác vụ với DB của 1 table nào đó
(ví dụ: UserRepo sẽ làm việc với UserEntity và thực hiện các thao tác thêm xóa sửa đối với bảng User)
2. Service: sẽ chỉ làm việc với Repo và 3rd nếu có để cung cấp n-method cho 1 service nào đó. 1 Service có thể inject n-dependencies bao gồm các repo.
(ví dụ: AuthUserService sẽ làm việc với UserRepo, UserPermissionRepo, CryptoXXX (3rd) để cung cấp các method như RegisterUser, LoginUser ... vvv)
3. Controller/Func: sẽ chỉ làm việc với Service để thực thi các phương thức
(ví dụ: AuthController sẽ có API Login => trong đó sẽ call 2 action là AuthService.login và AuthService.getBasicInfo ... vvv)

Theo quan điểm của em thì nó là basic và flexible.. theo pattern này thì có thể apply cho bất kỳ ngôn ngữ nào.
Em có research thì cũng thấy các ref pattern giống giống cách của em .
https://exceptionnotfound.net/the-r...n-with-dependency-injection-and-asp-net-core/

Vấn đề là như vậy, em cũng trình bày với ae trong cty nhưng 4-10 người role cao hơn em ko đồng ý (em ko bàn tới skill của họ nhưng nếu họ giải thích được lí do chính đáng thì em ko comment), còn lại mấy ae dưới ko ý kiến -> 9/10.
Họ cho rằng controller nên gọi thẳng repository, còn service chỉ dùng cho 3rd.
logic nên implement luôn trong controller -> em có phản biện rằng có 1 số case cần dùng lại logic này thì ntn? thì ko trả lời được

Và do ý chỉ 1/10 nên cuối cùng thì ý kiến của em bị reject. Khi review code cũng bi soi khá nặng nề, hiuhiu
Các bác đã gặp hay có hướng xử lý nào cho trường hợp giống em không ?
Cá nhân cũng đang làm pattern như thím đang đề xuất.
Mình không đồng tình việc logic nằm ở tầng controller. Ai nói vì đơn giản vs dễ nên để thẳng controller luôn cũng đc mà ==> Đây là nguy biện, lý thuyết thì thế thiệt , nhưng anh em đi làm nghĩ lại đi project mà đơn giản vs ít logic đến mức để đc thẳng ở controller có bao nhiêu?

Controller là tầng giao tiếp gần vs client nên NẾU có thêm logic thì nó chỉ làm 2 nhiệm vụ: request/ response conversation và request data format & constraints validation
  • Ví dụ có ProductController và TProductController ( thrift ) đều gọi vô ProductService nhưng 1 cái cho http dữ liệu trả về dạng JSON, 1 cái cho Thrift api.
  • Sau này đẻ thêm 1 đầu controller cần data trả về xài Protobuf thì thêm controlller và để logic convert response . Còn service thì ko đổi j
 
Sửa lần cuối:
Em làm việc tại công ty X được 3 năm, ae toàn senior.
Tại 1 công ty Y em mới vào, tình hình là em và ae có một số ý kiến bất đồng trong việc phân tách các layers gồm Repository / Service và Controller/Serverless Func

Các bác lâu năm exp cho em hướng xử lý trong case này với.

Sơ sơ tình hình là với vấn đề trên, em sẽ chia ra các layer với reponsibility khác nhau.
1. Repo: sẽ làm việc với SQL và map vào entity. thực hiện các tác vụ với DB của 1 table nào đó
(ví dụ: UserRepo sẽ làm việc với UserEntity và thực hiện các thao tác thêm xóa sửa đối với bảng User)
2. Service: sẽ chỉ làm việc với Repo và 3rd nếu có để cung cấp n-method cho 1 service nào đó. 1 Service có thể inject n-dependencies bao gồm các repo.
(ví dụ: AuthUserService sẽ làm việc với UserRepo, UserPermissionRepo, CryptoXXX (3rd) để cung cấp các method như RegisterUser, LoginUser ... vvv)
3. Controller/Func: sẽ chỉ làm việc với Service để thực thi các phương thức
(ví dụ: AuthController sẽ có API Login => trong đó sẽ call 2 action là AuthService.login và AuthService.getBasicInfo ... vvv)

Theo quan điểm của em thì nó là basic và flexible.. theo pattern này thì có thể apply cho bất kỳ ngôn ngữ nào.
Em có research thì cũng thấy các ref pattern giống giống cách của em .
https://exceptionnotfound.net/the-r...n-with-dependency-injection-and-asp-net-core/

Vấn đề là như vậy, em cũng trình bày với ae trong cty nhưng 4-10 người role cao hơn em ko đồng ý (em ko bàn tới skill của họ nhưng nếu họ giải thích được lí do chính đáng thì em ko comment), còn lại mấy ae dưới ko ý kiến -> 9/10.
Họ cho rằng controller nên gọi thẳng repository, còn service chỉ dùng cho 3rd.
logic nên implement luôn trong controller -> em có phản biện rằng có 1 số case cần dùng lại logic này thì ntn? thì ko trả lời được

Và do ý chỉ 1/10 nên cuối cùng thì ý kiến của em bị reject. Khi review code cũng bi soi khá nặng nề, hiuhiu
Các bác đã gặp hay có hướng xử lý nào cho trường hợp giống em không ?
Thường thì em code cũng làm như của bác đưa ra. Controller chỉ để decode, gọi đến service, encode trả về.
Tuy nhiên thì việc tách ra một layer nữa có thể làm cho mọi người thấy không cần thiết vì ít có tính dùng chung của các hàm trong service với cả controller.
Hoặc cũng có thể bên bác muốn tách ra 1 phần chỉ để xử lý các 3rd package thôi. Nếu theo hướng này thì vẫn có thể làm như pattern của bác và thêm 1 tầng để xử lý 3rd.
 
Chỗ em mấy ông code xử lý hết trong controller, đẻ ra tầng service chỉ làm mỗi việc là return từ repo, nhiều xử lý giống nhau cứ nghe ông lead clone ra là xong. -_- nhìn rác vcc.
 
Nếu bạn muốn thay đổi. Hãy nói với người có thể quyết định, ở đây là lead.
Nếu các project mới vẫn hoạt động tốt và phù hợp với yêu cầu thì cứ làm theo.
Solution của bạn cần phải chứng minh là nó làm được những cái mà solution hiện tại ko làm được.
 
Chỗ em mấy ông code xử lý hết trong controller, đẻ ra tầng service chỉ làm mỗi việc là return từ repo, nhiều xử lý giống nhau cứ nghe ông lead clone ra là xong. -_- nhìn rác vcc.
Điều thím nói nó rác thì hơi định kiến.

Điều thím nói xảy ra khi logic rất đơn giản, dạng simple CURD. Nhưng đời nào đơn giản thế.
 
Ý kiến của mình là nên làm như chủ xị. Tức là Controller gọi service. Ko build logic trong controller.
Lý do: Để unit test. Để reusable. Để dependency injection.

Cái thứ 2 là controller có được phép gọi thẳng repository ko? Câu trả lời là có và không.

Nếu repo có hàm cung cấp đúng dữ liệu cần thì ko cần qua service vì như vậy sẽ xảy ra function proxy ( function wrapper). Đó là lý thuyết (có) Nhưng cái này trong thực tế khó có trường hợp vậy (không)

Lý do: Repo thường là trả về full entity mà controller nó chỉ cần một phần trong đó thôi nên cần có service để bỏ bớt hoặc format lại dữ liệu. Cho nên thưc tế controller gọi thẳng repo là cực hiếm.
 
nghe nói toàn lý thuyết. thế ông trình bày hay thế sao ae k theo cách của ông? tôi muốn nghe ý kiến trong buổi đó tại sao ng ta bác đi:rolleyes:
 
Bên mình chia code theo feature, bạn đọc cách chia thư mục cho dự án trên mạng thì biết. Nên chia theo feature (như user, product) không theo role (repository, entity).

Code dùng chung cho vô thư mục services hay utils.
Mỗi feature thì có thể sử dụng cấu trúc thư mục khác nhau cũng được, nó có một số model(entity) của riêng mình và có thể dùng đọc model(entity) của feature khác.

Feture này ghi dữ liệu phần model của feature khác bằng cách gửi message qua message queue hoặc feature có public function để gọi, hoặc cũng có thể gọi qua rest api.

Logic của feature nào thì feature đó xử lý.

Quan trọng nhất là tách feature ra với giữ lại cái function ghi dữ liệu cho feature khác xài. Khi refactor hay upgrade tính năng thì chỉ giữ lại public function này là được.

Bạn chia theo role kiểu kia thì không biết cái sevice nào phụ thuộc cái nào. Nếu sửa 1 cái service thì không biết cái khác có ảnh hưởng không.
 
Bên mình chia code theo feature, bạn đọc cách chia thư mục cho dự án trên mạng thì biết. Nên chia theo feature (như user, product) không theo role (repository, entity).

Code dùng chung cho vô thư mục services hay utils.
Mỗi feature thì có thể sử dụng cấu trúc thư mục khác nhau cũng được, nó có một số model(entity) của riêng mình và có thể dùng đọc model(entity) của feature khác.

Feture này ghi dữ liệu phần model của feature khác bằng cách gửi message qua message queue hoặc feature có public function để gọi, hoặc cũng có thể gọi qua rest api.

Logic của feature nào thì feature đó xử lý.

Quan trọng nhất là tách feature ra với giữ lại cái function ghi dữ liệu cho feature khác xài. Khi refactor hay upgrade tính năng thì chỉ giữ lại public function này là được.

Bạn chia theo role kiểu kia thì không biết cái sevice nào phụ thuộc cái nào. Nếu sửa 1 cái service thì không biết cái khác có ảnh hưởng không.
nói chung là tổ chức thiếu gì style. quan trọng là phù hợp k thôi
 
à mình chia như bác nói đó, CustomerValidator chẳng hạn, trong đó có validate create customer request, validate date of birth ..., kiểu vậy đó bác.

À mà bên mình từ Service không gọi xuống các repo khác như bên bác, mà gọi qua các Service khác.

2. Service: sẽ chỉ làm việc với Repo và 3rd nếu có để cung cấp n-method cho 1 service nào đó. 1 Service có thể inject n-dependencies bao gồm các repo.
(ví dụ: AuthUserService sẽ làm việc với UserRepo, UserPermissionRepo, CryptoXXX (3rd) để cung cấp các method như RegisterUser, LoginUser ... vvv)

Bên mình thì AuthUserService sẽ làm việc với UserService, UserPermissionService .., kiểu vậy :adore:
Vậy bác cho em hỏi các services UserService, UserPermissionService thì có gọi xuống Repo không ?
=> Theo mình nghĩ cách bên bác cũng như của chủ thớt, có điều ở 1 số services có tính chất riêng sẽ tách ra và re-use lại các services có sẵn. Có phải thế không nhỉ ?
 
Theo mình số đông sẽ làm theo cách của thím thớt. Implement logic và gọi thẳng Repo trong controller thực sực không hay, như thớt nói về reuseable chẳng hạn, cấu trúc code sẽ tách biệt rành mạch, ví dụ ngày đẹp trời nào đó services nó trở nên phình to quá và có nhiều function hay ho cần dùng cho project khác thì bác có thể tách hẳn cục service ra 1 project xem như 1 dependency. Hơn nữa controller sẽ trở nên hỗn độn và mất đi ý nghĩa thực sự của nó. Các bác ở cty reject ý của thím chắc là code quen tay, không muốn thay đổi, code ở controller có gì cứ vào đó tìm thay vì chạy tới các chỗ khác nhau :D
 
Theo mình số đông sẽ làm theo cách của thím thớt. Implement logic và gọi thẳng Repo trong controller thực sực không hay, như thớt nói về reuseable chẳng hạn, cấu trúc code sẽ tách biệt rành mạch, ví dụ ngày đẹp trời nào đó services nó trở nên phình to quá và có nhiều function hay ho cần dùng cho project khác thì bác có thể tách hẳn cục service ra 1 project xem như 1 dependency. Hơn nữa controller sẽ trở nên hỗn độn và mất đi ý nghĩa thực sự của nó. Các bác ở cty reject ý của thím chắc là code quen tay, không muốn thay đổi, code ở controller có gì cứ vào đó tìm thay vì chạy tới các chỗ khác nhau :D
Nói rõ ra thì thấy cũng không hay lắm nhưng mong bác hiểu phần nào cảm giác khi nói về tích phân cho hs lớp 9 => 100% thấy ko hay và ko nên xài, rắc rối, **** tạp.
Sao mình nói như vậy, lí do là hình như 4 ông kia không hề biết tới pattern này. Mình có dẫn chứng, cũng không thèm đọc cho rằng như vậy là quá phức tạp và rối rắm trong khi mình thấy nó khá clear và basic... vậy thôi, đủ hiểu trình ae tới đâu. Cảm thấy không được thì bay cty khác v :v
 
Đợt maintain cái project cũ. Mấy ông viết hết cả logic trong controller đọc mà xoắn mẹ não. Sau refactor lại thành service cho từng cụm feature code clean hẳn. Viết unit test cũng đỡ thốn hơn
 
Controller mà gọi trực tiếp Repo thì là làm biếng hoặc lười thôi, chưa nghĩ ra lý do gì để xem đó là good practice :(
 

Thống kê chủ đề

Ngày tạo
soledad86,
Người trả lời cuối
freedom.9,
Trả lời
217
Lượt xem
33.247
Quay lại
Lên đầu trang