Nguyên lý SOLID là gì? Nguyên lý SOLID trong Node.js với TypeScript

2073
nguyên lý SOLID là gì

Với những bạn lập trình Java thì có lẽ biết rất rõ nguyên lý SOLID là gì rồi. Với Java thì SOLID gần như là quy tắc bất di bất dịch mà mọi lập trình viên phải nắm vững.

Tuy nhiên, với Node.js hay Javascript nói chúng thì lại rất dễ dãi. Bạn viết code kiểu gì cũng được, bạ đâu viết đấy cũng được và tùy thuộc style code của mỗi người. Chính vì điều này mà Node.js/Javascript cực dễ học.

Nhưng vì viết code thoải mái, không có quy tắc sẽ dẫn đến dự án khó maintain, code sẽ rất rối, khó debug… Chính vì vậy, nếu có thể áp dụng được nguyên tắc SOLID cho dự án Node.js thì thật tuyệt.

Bài viết này mình sẽ chia sẻ cách thực hiện nguyên lý SOLID trong Node.Js với sự hỗ trợ của TypeScript.

  Tìm hiểu về nguyên lý "vàng" SOLID trong lập trình hướng đối tượng
  Nodejs và PHP? Bạn chọn công nghệ web nào?

Nguyên lý SOLID là gì?

Nguyên lý SOLID là nguyên lý với 5 nguyên tắc, tương ứng với các chữ cái viết tắt trong tên là:

  • Single Responsibility Principle
  • Open Closed Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle
nguyên lý SOLID là gì

Nguyên lý SOLID trong Node.js

Single responsibility principle

Được hiểu như sau:

Ví dụ sau mình tạo một class Person bằng TypeScript. Trong đó mình định nghĩa các thuộc tính của một người như Tên, đệm, thông tin liên hệ( email), và các hành động chào hỏi – greet(), xác thực email – validateEmail().

Nhìn qua class trên bạn thấy ngay rằng có chi tiết thừa. Đó chính là hàm validateEmail(), vì hành động này không phải là hành vi của một người. Không nên đặt hàm này trong class Person.

Chúng ta có cải tiến đoạn code như sau:

Open/close principle

Có thể hiểu nguyên tắc này như sau:

Điểm mấu chốt của nguyên tắc này là: Chỉ được THÊM mà không được SỬA.

Đoạn code dưới đây là một ví dụ cho vi phạm nguyên tắc này:

Đoạn code cho phép chúng ta tính diện tích của hình chữ nhật và hình tròn. Nếu giờ mình muốn mở rộng chương trình, muốn hỗ trợ thêm hình tam giác nữa. Vậy phải làm sao?

Mình sẽ phải SỬA code của hàm getArea(). Mà làm như vậy là vi phạm nguyên tắc rồi.

Để cải thiện, chúng ta sửa lại thành như sau:

Với code mới này, để hỗ trợ thêm một hình dạng mới, bạn chỉ cần tạo THÊM một class và implement interface Shape là được, không cần phải sửa code đã có.

Liskov substitution principle

Với nguyên tắc này khuyến khích chúng ta sử dụng tính đa hình trong lập trình hướng đối tượng.

Xem thêm các tính chất đặc thù trong lập trình hướng đối tượng.

Quay lại đoạn code của ví dụ trước:

Chúng ta đã sử dụng interface Shape để đảm bảo chương trình có thể mở rộng mà không cần phải sửa code đã có.

Nguyên tắc thay thế Liskov cho chúng ta biết rằng chúng ta có thể chuyển bất cứ kiểu con nào của Shape( Ví dụ: Rectangle, Cyrcle…) sang hàm getArea() mà không làm thay đổi tính chính xác của chương trình.

Trong các ngôn ngữ lập trình kiểu như TypeScript/Java, thì trình biên dịch sẽ kiểm tra đã implement chính xác interface đó chưa( Nếu implement mà không override đủ method là bị lỗi biên dịch ngay). Nên bạn không phải làm thủ công để đảm bảo chương trình tuân thủ nguyên tắc Liskov.

Interface segregation principle

Vẫn lấy đoạn code tính diện tích hình chữ nhật và hình tròn. Bây giờ có một vấn đề là: Nếu bạn sử dụng đoạn code cho nhiều mục đích khác nhau thì sao?

Nếu mình muốn tính diện tích xong rồi thì mã hóa thành JSON và trả về cho client. Nếu mình code như sau thì sẽ vi phạm nguyên tắc thứ 4 này.

Vi phạm bởi vì: Có lúc mình dùng không cần phải mã hóa thành JSON để trả cho client, có lúc mình lại cần JSON. Đoạn code đã mix cả hai mục đích ấy vào cùng một interface.

Xem thêm JSON là gì?

Để tốt hơn thì nên tác interface ra.

Khi không cần mã hóa JSON.

Và khi cần mã hóa thành JSON.

Các bạn thấy code “ngon” hơn chưa?

Dependency inversion principle

Đây là nguyên tắc quan trọng nhất trong nguyên lý SOLID. Nhưng vì nó là chữ D trong cụm từ SOLID nên luôn được giải thích sau cùng.

Nếu chúng ta xem lại các ví dụ ở các nguyên tắc trên, chúng ta thấy rằng interface là một yếu tố cơ bản nhất của mọi nguyên tắc. Và nguyên tắc dependency inversion chính là tổng hợp của 4 nguyên tắc trước.

Kết luận

Việc thực hiện nguyên lý SOLID trong các ngôn ngữ lập trình không hỗ trợ Interface như Javascript ES5, thậm chí ES6 thật là khiêm cưỡng. Nhưng với hỗ trợ của TypeScript thì lại thật tuyệt.

Hy vọng qua bài viết này, các bạn có thể nắm được nguyên lý SOLID là gì, và cách ứng dụng nguyên lý SOLID trong Node.js với TypeScript.

Đừng bỏ lỡ một số bài viết hay về:

Xem thêm việc làm Node.JS Developers hot nhất trên TopDev

TopDev via VNTALKING

  CÁCH TẠO MỘT DOCKER ĐƠN GIẢN CHO NODE.JS
  Tìm hiểu về Asynchronous của Node.js