Sử dụng Laravel cho ứng dụng/dự án lớn có tốt không?

0
32

Chúng ta đều biết rằng, Laravel là Framework PHP phổ biến nhất cho đến ngày nay. Cấu trúc thư mục của nó là tốt, được tổ chức tốt, tinh gọn và đơn giản. Làm việc với cấu trúc dự án mặc định do Laravel cung cấp là hoàn toàn tốt khi làm việc trong một dự án nhỏ hoặc vừa. Nhưng, khi nó là một ứng dụng lớn với hơn 50 mô hình, đó là lúc chúng ta bắt đầu nghẹt thở trên cơ sở mã của riêng mình.

Duy trì một ứng dụng lớn không phải là trò đùa. Đặc biệt, khi nó không được tổ chức đúng. Và cấu trúc mặc định của Laravel chắc chắn không hữu ích lắm cho kịch bản này.

Nhưng trước tiên, hãy xem cấu trúc mặc định và những gì nó trở thành cho các ứng dụng lớn.

Cấu trúc ứng dụng mặc định của Laravel tựa như thế này-

|- app/
|- Console/
|- Commands/
|- Events/
|- Exceptions/
|- Http/
|- Controllers/
|- Middleware/
|- Jobs/
|- Listeners/
|- Providers/
|- User.php
|- database/
|- factories/
|- migrations/
|- seeders
|- config/
|- routes/
|- resources/
|- assets/
|- lang/
|- views/

Không có gì sai với cấu trúc. Nhưng, khi chúng ta làm việc trong một ứng dụng lớn; chúng tôi thường phân chia logic kinh doanh của chúng tôi thành Kho, Transformers, vv. một cái gì đó như sau-

|- app/
|- Console/
|- Commands/
|- Events/
|- Exceptions/
|- Http/
|- Controllers/
|- Middleware/
|- Jobs/
|- Listeners/
|- Models/
|- Presenters/
|- Providers/
|- Repositories/
|- Services/
|- Transformers/
|- Validators/
|- database/
|- factories/
|- migrations/
|- seeders
|- config/
|- routes/
|- resources/
|- assets/
|- lang/
|- views/

Đây rõ ràng là một dự án Laravel có cấu trúc tốt. Bây giờ, hãy xem bên trong thư mục Mô hình

|- app/
|- Models/
|- User.php
|- Role.php
|- Permission.php
|- Merchant.php
|- Store.php
|- Product.php
|- Category.php
|- Tag.php
|- Client.php
|- Delivery.php
|- Invoice.php
|- Wallet.php
|- Payment.php
|- Report.php

Chà, nó không tệ chút nào. Chúng tôi cũng có Dịch vụ xử lý tất cả các logic kinh doanh. Ngoài ra còn có thư mục Kho lưu trữ, Máy biến áp, Trình xác thực có cùng hoặc nhiều số lớp bên trong chúng. Nhưng, làm việc trên một Thực thể / Mô hình duy nhất yêu cầu điều hướng qua các thư mục và tệp khác nhau. Một số người có thể thấy nó rất mệt mỏi nhưng những người khác vẫn còn okey với nó.

Vấn đề không nằm ở việc điều hướng các thư mục khác nhau mà là trong việc duy trì mã và liên lạc giữa các dịch vụ.

Hãy phân tích cơ sở mã và xem những gì chúng ta có thể tìm thấy –

  • Nó là một ứng dụng nguyên khối
  • Thật khó (đối với một số nhà phát triển) để duy trì
  • Năng suất thấp (cần phải suy nghĩ về kết nối liên tục mọi lúc)
  • Mở rộng quy mô là một vấn đề

Giải pháp rất rõ ràng – microservice. Ngay cả khi chúng tôi sử dụng SOA (Kiến trúc hướng dịch vụ), chúng tôi vẫn phải chia ứng dụng nguyên khối thành các phần độc lập nhỏ hơn để chia tỷ lệ chúng một cách riêng biệt.

Tuyệt vời, chúng tôi có một giải pháp. Vậy thì tại sao chúng ta chỉ làm điều đó? Chia mã thành các phần nhỏ hơn. Rõ ràng là nói dễ hơn làm!

Thông thường, tách một dịch vụ đòi hỏi hai bước đơn giản-

  • Chuyển dịch vụ trẻ em (Mô hình, Kho lưu trữ, Transformers, v.v.) sang một ứng dụng microservice PHP nhỏ hơn mới.
  • Yếu tố lại chức năng dịch vụ gọi để chuyển hướng mục tiêu đến microservice (ví dụ: tạo yêu cầu HTTP).

Nhưng bây giờ bạn cần tìm tất cả các tệp liên quan đến dịch vụ đó. Và thật ngạc nhiên, bạn có thể phát hiện ra rằng bạn đã sử dụng mô hình hoặc kho lưu trữ của nó ở một nơi khác trong mã bằng cách bỏ qua dịch vụ (tôi đã làm điều này trong quá khứ). Nhưng đây không phải là vấn đề duy nhất, có nhiều hơn. Và nếu chúng ta tổng hợp chúng-

  • Có quá nhiều tập tin để xem xét
  • Cơ hội phạm sai lầm cao
  • Tạo ra sự thất vọng của nhà phát triển
  • Cần phải xem xét lại logic miền đôi khi
  • R.I.P nhà phát triển mới 🙂

Lý do cuối cùng là rất quan trọng bởi vì rất khó để một nhà phát triển mới có thể nắm bắt toàn bộ ứng dụng trong một thời gian ngắn. Nhưng, người quản lý dự án sẽ không cho anh ta nhiều thời gian. Điều này dẫn đến việc vá khỉ, đặt mã sai và nhà phát triển mới tiếp theo sẽ bối rối hơn.

May mắn thay, chúng tôi đã có một giải pháp – HMVC. Chia toàn bộ ứng dụng thành các phần nhỏ hơn, trong đó mỗi phần có các tệp và thư mục riêng như ứng dụng / thư mục và được tải thông qua composer.json tự động tải, như sau

|- auth/
|- Exceptions/
|- Http/
|- Listeners/
|- Models/
|- Presenters/
|- Providers/
|- Repositories/
|- Services/
|- Transformers/
|- Validators/
|- merchant/
|- Console/
|- Events/
|- Exceptions/
|- Http/
|- Jobs/
|- Listeners/
|- Models/
|- Presenters/
|- Providers/
|- Repositories/
|- Services/
|- Transformers/
|- Validators/
|- database/
|- factories/
|- migrations/
|- seeders
|- config/
|- routes/
|- resources/
|- assets/
|- lang/
|- views/

Nhưng HMVC thêm phức tạp hơn và khi chúng tôi muốn chuyển một Module cụ thể vào microservice; chúng ta vẫn cần giữ các bộ điều khiển, phần mềm trung gian, … trong cơ sở mã chính. Hầu hết thời gian, chuyển sang microservice yêu cầu xác định lại các tuyến và bộ điều khiển. Vì vậy, chúng tôi phải làm công việc dư thừa.

Thiết kế hướng tên miền có thể là một giải pháp

Không có giải pháp hoàn hảo. Mọi thứ đều có sự đánh đổi. Nhưng mọi người đều có một sở thích. Tôi sẽ không thảo luận về Thiết kế hướng tên miền (DDD) ở đây. Nhà phát triển DeLaUnu đã viết một mô tả tuyệt vời về DDD tại đây.

Theo quan điểm của tôi, DDD (có thể) cấu trúc ứng dụng Laravel của bạn thành 4 phần (hoặc 3 Nhận xem như thế nào) –

Ứng dụng – thường giữ, Bộ điều khiển, Middleware, Tuyến
Tên miền – thường chứa logic kinh doanh (Mô hình, Kho lưu trữ, Biến áp, Chính sách, v.v.)
Cơ sở hạ tầng Trực tiếp giữ các dịch vụ phổ biến như Đăng nhập, Email, v.v.
Giao diện trực tiếp giữ quan điểm, lang, tài sản.

Nếu nó dễ dàng như vậy thì tại sao don Patrick chúng tôi cấu trúc ứng dụng của chúng tôi như thế này và sử dụng Namespace?

|- app/
|- Http/ (Application)
|- Controllers/
|- Middleware/
|- Domain/
|- Models/
|- Repositories/
|- Presenters/
|- Transformers/
|- Validators/
|- Services/
|- Infrastructure/
|- Console/
|- Exceptions/
|- Providers/
|- Events/
|- Jobs/
|- Listeners/
|- resources/ (Interface)
|- assets/
|- lang/
|- views/
|- routes/
|- api.php
|- web.php

Bởi vì, chia dự án thành các thư mục sẽ không hoạt động. Nó chỉ có nghĩa là chúng tôi không thêm gì ngoài Namespace.

Khoảnh khắc của sự thật

Đến lúc này có lẽ bạn đã khó chịu và chỉ muốn xem giải pháp. Vì vậy, đây là:

|- app/
|- Http/
|- Controllers/
|- Middleware/
|- Providers/
|- Account/
|- Console/
|- Exceptions/
|- Events/
|- Jobs/
|- Listeners/
|- Models/
|- User.php
|- Role.php
|- Permission.php
|- Repositories/
|- Presenters/
|- Transformers/
|- Validators/
|- Auth.php
|- Acl.php
|- Merchant/
|- Payment/
|- Invoice/
|- resources/
|- routes/

Auth.php và Acl.php là các tệp dịch vụ bên trong thư mục ứng dụng / Tài khoản /. Bộ điều khiển sẽ chỉ truy cập hai lớp này và gọi các chức năng của chúng. Các lớp khác (bên ngoài miền) sẽ không bao giờ biết về các lớp còn lại trong thư mục ứng dụng / Tài khoản /. Các hàm bên trong các dịch vụ này sẽ chỉ nhận các kiểu dữ liệu PHP cơ bản như mảng, chuỗi, int, bool và POPO (Plain Old PHP Object) nhưng không có các thể hiện lớp. Ví dụ:


public function register(array $attr) {

}public function login(array $credentials) {

}public function logout() {

}

Lưu ý rằng hàm thanh ghi nhận một mảng các thuộc tính thay vì đối tượng Người dùng. Điều này rất quan trọng vì lớp khác đang gọi hàm không giả sử biết sự tồn tại của mô hình Người dùng. Đây là quy tắc cơ bản của toàn bộ cấu trúc này.

Khi chúng tôi muốn tách mã

Ứng dụng của chúng tôi đã trở nên lớn và chúng tôi muốn tách miền Tài khoản thành một dịch vụ siêu nhỏ riêng biệt và biến nó thành máy chủ OAuth.

Vì vậy, chúng tôi chỉ di chuyển các phần sau đây:

|- Account/
|- Console/
|- Exceptions/
|- Events/
|- Jobs/
|- Listeners/
|- Models/
|- User.php
|- Role.php
|- Permission.php
|- Repositories/
|- Presenters/
|- Transformers/
|- Validators/
|- Auth.php
|- Acl.php

Đối với một ứng dụng Laravel hoàn toàn mới (hoặc có thể là Lumen)

|- app/
|- Http/
|- Controllers/
| - Middleware/
|- Account/
|- Events/
|- Jobs/
|- Listeners/
|- Models/
|- User.php
|- Role.php
|- Permission.php
|- Repositories/
|- Presenters/
|- Transformers/
|- Validators/
|- Auth.php
|- Acl.php
|- routes/
|- resources/

Tất nhiên, chúng ta phải viết mã trong bộ điều khiển và tuyến đường vì chúng ta cần biến nó thành máy chủ OAuth.

Nhưng những thay đổi nào chúng ta cần thực hiện trong cơ sở mã chính?

Chúng tôi chỉ giữ các tệp Dịch vụ Auth.php và Acl.php và thay đổi mã bên trong các chức năng của chúng thành các yêu cầu HTTP (hoặc các phương thức khác như nhắn tin) nhắm mục tiêu microservice mới được tạo.


public function login(array $credentials) {
// change the code here
}

Toàn bộ ứng dụng sẽ giữ nguyên. Và cấu trúc ứng dụng sẽ như thế này

|- app/
|- Console/
|- Exceptions/
|- Http/
|- Controllers/
|- Middleware/
|- Providers/
|- Account/
|- Auth.php
|- Acl.php
|- Merchant/
|- Payment/
|- Invoice/
|- resources/
|- routes/

Và với ít nỗ lực này, bạn có thể chuyển một phần mã của mình thành một dịch vụ siêu nhỏ hoàn toàn riêng biệt. Tôi không thể nghĩ ra bất kỳ cách nào khác để làm ít nhất có thể trong khi chuyển một phần mã vào microservice.

Đánh đổi

Như tôi đã nói trước đây, mọi thứ đều có sự đánh đổi, giải pháp này không khác. Và, ở đây chúng tôi có một vấn đề liên quan đến việc di chuyển! Bởi vì trong cấu trúc thư mục trên (trước khi phân tách), tất cả các tệp di chuyển đều nằm trong thư mục cơ sở dữ liệu / di chuyển /. Nhưng khi chúng ta muốn tách một tên miền, chúng ta cũng cần xác định và di chuyển các di chuyển của tên miền đó. Điều này có thể khó khăn vì chúng tôi không có bất kỳ dấu hiệu rõ ràng nào về việc di chuyển thuộc về miền nào. Chúng tôi một số cách cần đặt một định danh trong các tệp di chuyển.

Mã định danh đó có thể là tiền tố tên miền. Ví dụ: chúng ta có thể đặt tên tệp di chuyển là xxxxxxxxx_create_account_users_table.php thay vì xxxxxxxxx_create_users_table.php. Chúng tôi cũng có thể sử dụng tên bảng account_users thay vì tắt người dùng nếu chúng tôi muốn. mà tôi thích xác định bảng nào sẽ di chuyển trong khi tách. Việc tách các tệp di chuyển có thể gây ra một chút bực bội nhưng nếu chúng ta sử dụng tiền tố hoặc bất kỳ loại điểm đánh dấu nào, quá trình chắc chắn sẽ trở nên ít đau đớn hơn.

Tôi vẫn đang thử nghiệm cấu trúc và kế hoạch xây dựng gói Laravel sẽ cung cấp các lệnh thủ công để tự động hóa quá trình tạo và tách tệp. Tôi sẽ thêm liên kết gói ở đây khi nó được thực hiện.

Xem thêm: 7 lý do nên chọn Famework Laravel

Tham khảo khóa học Laravel tại Hà Nội

LEAVE A REPLY

Please enter your comment!
Please enter your name here