Kiến trúc hệ thống trên Laravel - Phần 1

 

Xin chào các bạn. Mình vào nghề lập trình cũng đã lâu, cũng có 1 số hiểu biết coi như là nâng cao về framework Laravel. Nên hôm nay mình xin chia sẻ 1 chút về kiến trúc hệ thống của mình được xây dựng trên Laravel như thế nào. Mong rằng có thể giúp ích cho các bạn :).

Đây sẽ là 1 series gồm 1 số phần như sau:

  • Kiến trúc hệ thống trên Laravel - Phần 1  : Tại sao phải áp dụng architect vào trong Laravel
  • Phần 2 : OOP, Interface, Dependency Injection, IoC
  • Phần 3: Phân tích sâu vào việc sử dụng interface
  • Phần 4 : Design Pattern – Decorator
  • Phần 5 : Design Pattern – Adapter
  • Phần 6 : Design Pattern – Repository
  • Phần 7 : Design Pattern – Factory
  • Phần 8 : Advance component trong Laravel
  • Phần 9 : Mô hình kiến trúc cụ thể Part 1
  • Phần 10 : Mô hình kiến trúc cụ thể Part 

I. Tại sao phải áp dụng architect vào trong Laravel

OK. Hôm nay chúng ta sẽ đi vào phần đầu tiên “Tại sao lại phải áp dụng kiến trúc vào trong Laravel” ^^.

Nếu là dân trong nghề, ai cũng biết framework Laravel hiện đang thông dụng nhất trong PHP. Laravel rất tốt, có nhiều component / package kèm theo để chúng ta có thể dễ dàng mở rộng chức năng.

 

Thế thì cần quái gì phải áp dụng kiến trúc vào Laravel để làm gì, cứ add package vào sử dụng 
có phải là xong không :D?

 

Ha ha, sẽ có rất nhiều bạn hỏi mình như vậy. Và nói thật, các bạn nói hoàn toàn đúng. Với những hệ thống nhỏ, cần xây dựng nhanh và các bạn không cần quan tâm đến tính tái sử dụng các component trong hệ thống đó thì cứ MVC bình thường của Laravel mà chiến ^^.

 

Vậy cái kiến trúc của ông có hơn quái gì MVC của Laravel mà ông đòi khoe?

 

Chuẩn luôn, áp dụng kiến trúc vào trong Laravel để làm gì trong khi Laravel làm được quá nhiều thứ ^^. Xin thưa với các bạn rằng, nếu chúng ta không đặt mục tiêu dự án nào cũng phải viết lại từ đầu thì chúng ta phải có 1 số cách để có thể tái sử dụng các component xịn mà chúng ta đã viết từ dự án này sang dự án khác. Mục tiêu áp dụng kiến trúc là tăng tính linh hoạt và khả năng tái sử dụng trong hệ thống

 

Vớ vẩn cái ông này, Laravel có composer package, khả năng linh hoạt và tái sử dụng tối đa 
rồi còn gì nữa

 

Vâng, Laravel rất linh hoạt. Nhưng chúng ta sử dụng cái linh hoạt đó của Laravel mà không đúng cách chính là nguyên nhân hạn chế cái sự linh hoạt của Laravel :D. Có phải các bạn đang sử dụng trực tiếp các package thẳng vào trong controller / model đúng không? Có khi nào bạn tự hỏi nếu package đó bị ngừng phát triển, hoặc không đáp ứng được yêu cầu mới phát sinh dẫn tới việc bạn phải áp dụng 1 cái package mới vào trong hệ thống. Khi đó, effort / cost bạn bỏ ra để thay thế package mới vào sẽ mất công đến nhường nào?

Chúng ta sẽ đi định nghĩa lại từ “linh hoạt” ở đây có nghĩa là gì ^^.

Chắc tất cả mọi người đều đồng ý với mình là code chính là phản ánh cuộc sống đời thời vào trong 1 chương trình / 1 website. Vậy chúng ta hãy xem hiện tại cuộc sống thực tế đang sản xuất ra các sản phẩm như thế nào rồi chúng ta cố gắng bê nguyên những cái nguyên lý đó vào trong cuộc đời coder của chúng ta :).

Lấy ví dụ về việc sản xuất điện thoại di dộng đi. Bạn cũng thấy con chip cho mobile ngon nhất ở thời hiện tại đang là snapdragon 820 / 821. Nói về con chíp snapdragon 820 thì nó xuất hiện trên rất nhiều dòng điện thoại, có thể kể ra Samsung Galaxy S7, S7 edge, LG G5, HTC 10, Sony Xperia XZ … Nhưng ví dụ ở dòng điện thoại Samsung S7, S7 edge đâu chỉ sử dụng chip Snapdragon của Qualcomm, nó còn sử dụng dòng chíp riêng do Samsung tự phát triển Exynos 8890.

Vậy thế quái nào mà 1 con chip lại được sử dụng được ở nhiều dòng điện thoại, nhiều hãng khác nhau. 
Và 1 dòng điện thoại lại có thể sử dụng được nhiều còn chip khác nhau.

 

Câu trả lời ở đây theo mình là chuẩn (standard). Các dòng chip được sản xuất theo 1 chuẩn nhất định, các hãng gia công điện thoại chỉ cần sản xuất mainboard của mình theo đúng chuẩn đó là có thể sử dụng được con chip đó rồi. Tương tự nếu trên mainboard đó hỗ trợ nhiều chuẩn kết nối chip thì có thể sử dụng được nhiều loại chip khác nhau rồi. Một ví dụ về chuẩn nữa là từ khi cổng usb / hdmi / usb-type c … được đưa thành standard thì ngành gia công phụ kiện đã mở ra 1 chương mới, tăng trưởng ở mức chóng mặt. Chứ cách đây 10-15 năm, từ khi điện thoại mới ra đời, mỗi ông có 1 cách kết nối khác nhau thì ngành phụ kiện điện thoại có cái gì đâu :D. Nói như vậy để chúng ta phải thông nhất với nhau standard là rất quan trọng, có standard thì mới có sự linh hoạt (flexible). Vậy linh hoạt ở đây có nghĩa là các component trong 1 hệ thống kết nối với nhau theo các standard nhất định, và từ đó chúng ta có thể sử dụng các biến thể khác nhau của các component trong cùng 1 hệ thống 1 cách dễ dàng.

Bê nguyên cái tư tưởng này vào trong lập trình thì các bạn sẽ thấy tính linh hoạt ở đây cũng sẽ giống hệt với tính linh hoạt ở trong thực tế thôi :)).

 

Vậy standard kết nối trong lập trình là gì?

 

Nó chính là interface trong OOP đấy các bạn ạ. Chúng ta sẽ đi sâu vào vấn đề này trong các phần sau. Nhưng hiện tại mình cần các bạn nhận thức được các bạn khi code phải sử dụng interface / abstract class thì hệ thống mới linh hoạt được.

Rồi, mỏi tay quá, bài viết cũng đã dài. Mình xin phép được kết luận ở đây.

Chúng ta áp dụng kiến trúc code vào trong Laravel để tăng tính linh hoạt và khả năng tái sử dụng của hệ thống. Để làm điều này chúng ta phải thay đổi tư tưởng của bản thân mình về cách xây dựng 1 hệ thống.

Thay vì suy nghĩ việc xây dựng hệ thống là việc gắn kết các component có các liên quan chặt (tightly coupled) với nhau, tức là giữa các component có sự phụ thuộc lẫn nhau. Ví dụ như bạn sử dụng method của 1 package ngay trong controller / model là bạn đã gắn chặt các component với nhau rồi đó. Khi đó việc thay đổi 1 component có thể sẽ có ảnh hưởng tới nhiều component khác. Ví dụ như bạn sử dụng 1 / nhiều method của 1 package trong các controller / model khác nhau, khi bạn chuyển sang 1 package khác không có method đó thì bạn phải đi tìm và sửa lại ở tất cả các controller / model mà đã sử dụng package cũ.

Do vậy chúng ta phải quan niệm việc xây dựng hệ thống là việc kết nối các component có quan hệ lỏng leo (giữa các component không có sự phụ thuộc – dependency là tốt nhất) thông qua các chuẩn kết nối (Nhắc lại 1 lần nữa – standard kết nối ở đây chính là OOP interface ^^). Do có quan hệ lỏng lẻo (loosely couped) nên việc thay thế biến thể trong 1 component (ví dụ như sử dụng các package khác nhau cho 1 mục đích) là hoàn toàn dễ dàng và không ảnh hưởng tới các component khác miễn sao vẫn tuân theo các chuẩn kết nối với nhau.

 

Cám ơn bạn đã đủ kiên nhẫn để đọc 1 bài khá dài. Hi vọng mình đã tiêm nhiễm vào trong đầu các bạn 1 suy nghĩ / 1 mở đầu đủ tốt để chúng ta sẽ dần dần khám phá vẻ đẹp của lập trình ^^. Hẹn gặp lại các bạn ở những phần sau.

Nguồn: http://blog.portalbeanzvn.com/kien-truc-he-thong-tren-laravel-phan-1/