Làm các nào để apply Design Pattern vào công việc hàng ngày

Bài viết được lấy từ tác giả Nguyễn Thế Huy

Bài viết này sẽ dành cho một chủ đề muôn thủa: "Làm các nào để apply Design Pattern vào công việc hàng ngày" ?

Các mẫu thiết kế (Design Pattern - DP), đặc biệt là các DP trong Lập trình hướng đối tượng như Factory, Strategy, Observer ... từ lâu đã không còn xa lạ gì với mọi người. Nếu dạo quanh một vòng Github, Gitlab, bạn sẽ không khó để gặp các Repo implement toàn bộ các DP này bằng rất nhiều ngôn ngữ lập trình. Tuy nhiên cái khó là làm sao mình nhận biết để áp dụng nó trong bài toán thực tế, vấn đề này không chỉ các bạn junior gặp phải, mà thậm chí là cả các bạn đã có nhiều năm kinh nghiệm.

Một số hiểu lầm mình thấy nhiều bạn mắc khi nói đến DP:

  1. DP chỉ dành cho người có kinh nghiệm: Sự thật là nếu bạn follow các bài viết của mình hoặc lần trình bày gần nhất của mình tại event Laravel VN tại HN, DP nó cực kỳ đơn giản và gần gũi, và bất cứ level nào cũng có thể áp dụng dễ dàng. (Nhưng mà biết đâu áp dụng DP có thể giúp anh em được tăng lương thì sao, hehehe 😃)
  2. Áp dụng DP làm chậm quá trình phát triển: Một số bạn cho rằng việc sử dụng DP rất mất thời gian (vì phải sinh thêm class, các lớp abstract, interface), do đó để tối ưu thì cần code chạy được trước đã. Điều này sẽ không đúng nếu các bạn đã thuần thục DP, thì chi phí áp dụng và maintain sẽ được giảm đi đáng kể, trải nghiệm lập trình cũng tốt hơn nhiều (Với bọn mình thời gian maintain có thể giảm tới 80%)

Để áp dụng DP cho use case của mình, các bạn có thể chú ý đến một số "dấu hiệu nhận biết" nhé:

  1. Seperation of Concern (Single Responsibility): Nguyên tắc đầu tiên của SOLID. Hãy cố gắng chia nhỏ class / function theo mục đích duy nhất. Ngay khi bạn nghĩ đến chia tách, bạn sẽ nảy ra ý tưởng để áp dụng DP. (Decorator pattern là một pattern rất hay dùng để chia tách các nhu cầu khác nhau).
  2. Chuẩn hóa xử lý thành các bước: Trước khi coding, bạn có thể ngẫm nghĩ một chút về cách thức xử lý logic. Nếu logic của bạn có thể được tách thành các bước xử lý liền nhau, Pipeline Design pattern sẽ là phù hợp. Nếu hành vi của một đối tượng có thể thay đổi qua các trạng thái (như đơn hàng, sản phẩm), State Pattern sẽ rất phù hợp đó.
  3. Che giấu sự hình thành đối tượng trong code: Thay vì liên tục xử lý new() trong code, hãy nghĩ tới Depedency Injection và Factory Pattern trong trường hợp này. Về cơ bản nếu code cần tới vài lượt if - else, hãy thử tách nó theo hướng Factory xem sao. Nếu đối tượng của bạn quá lớn, Builder Pattern sẽ phù hợp trong case này.
  4. Trừu tượng hóa: Nếu bạn có nhiều hơn một cách làm cho một tình huống: Ví dụ với case cổng thanh toán qua momo, vnpay, banking .... Strategy Pattern sẽ là một phương án phù hợp. Nếu các phương thức này có chung một số đặc điểm, và khác nhau ở cách thức triển khai một số phần, hãy nghĩ đến Template Design Pattern.
  5. "Sự kiện hóa": Với Laravel Event Listener, Observer Pattern chưa bao giờ đơn giản tới thế. Bạn có thể chuyển luồng xử lý dưới dạng handle các sự kiện xảy ra trong code. Đây cũng có thể là một cách giao tiếp giữa các module / package trong hệ thống của bạn.
  6. Cuối cùng, hãy luôn tự hỏi xem đoạn code mình viết ra có thực sự SOLID hay không ?.

Mình đính kèm một số hình ảnh use case thực tế việc refactor code sang sử dụng các DP thông dụng (có chú thích), hy vọng sẽ giúp ích các bạn trong việc áp dụng DP vào công việc hàng ngày 😃 (Mình sẽ update thêm sau cả khi bài viết được đăng)


Một số pattern như CommandBus, Singleton, ... mình đã có hẳn một bài riêng, các bạn có thể tìm lại các bài mình đã đăng trong group nhé.

Khôi Phạm
Khôi Phạm

Share is way to learn

SUNTECH VIỆT NAM   Đăng ký để nhận thông báo mới nhất