Nguyên lý thiết kế SOLID – SOLID Design Principles

Bài viết này viết bằng Tiếng Việt & Tiếng Anh. Cuộn trang xuống để xem phần Tiếng Anh.
This article is written in both Vietnamse & English. For English, please sroll down.

Mục tiêu của các nguyên lý thiết kế là tạo ra các cấu trúc phần mềm cấp trung bình:

  • Chịu đựng thay đổi,
  • Dễ hiểu, và
  • Là cơ sở của các component có thể được dùng trong nhiều hệ thống phần mềm.

SOLID (Tiếng Việt)

Single Responsiblity – Nguyên tắc trách nhiệm duy nhất

“Một mô-đun phải chịu trách nhiệm cho một, và chỉ một tác nhân.”

“Tác nhân” đề cập đến một nhóm một hoặc nhiều người yêu cầu thay đổi đó.

“Một mô-đun” hiểu là một tập hợp các chức năngcấu trúc dữ liệu, trước đây module là một file, nhưng dần các hệ thống lưu trữ không lưu source code dưới dạng file nữa.

Tách source code cho các tác nhân khác nhau là cần thiết.

Open-Closed – Nguyên tắc Đóng & Mở

“Cấu trúc phần mềm nên được mở để mở rộng nhưng bị đóng để sửa đổi.”

Nguyên tắc này thậm chí còn có ý nghĩa lớn hơn khi chúng ta xem xét ở cấp độ các thành phần kiến ​​trúc.

Việc phụ thuộc bắc cầu là vi phạm nguyên tắc chung.

Các bước để phân tích yêu cầu là:

  • Đầu tiên, hãy phân biệt trách nhiệm của từng bước.
  • Tiếp theo, tổ chức các phần phụ thuộc để đảm bảo các thay đổi đối với một trong các trách nhiệm đó không gây ra các thay đổi trong các quyền còn lại.

Liskov Substitution – Nguyên tắc thay thế Liskov

“Hình vuông không phải là một kiểu con của Hình chữ nhật”.

“Một trong những lỗi vi phạm đơn giản về qui tắc thay thế có thể khiến kiến ​​trúc của hệ thống bị vấn đục bởi một lượng đáng kể các chỉnh sửa.”

Nguyên tắc Liskov phát biểu: Nếu cứ mỗi đối tượng o1 của tập S có một o2 đối tượng của tập T sao cho tất cả chương trình P được xác định theo T. P không thay đổi khi o1 được thế bằng o2 ta gọi S sẽ là tập con của T.

Interface Segregation – Nguyên tắc Phân tách giao tiếp

“Phụ thuộc vào thứ gì đó đang mang một xe hành lý mà bạn không cần có thể gây ra cho bạn những rắc rối mà bạn không ngờ tới “.

Nguyên tắc phân tách giao tiếp (ISP) có thể được coi là một vấn đề ngôn ngữ hơn là một vấn đề kiến ​​trúc.

Trên thực tế, việc áp dụng ISP không chỉ trả lời trên loại ngôn ngữ, ta có thể tránh những lần deploy không cần thiết do phụ thuộc code.

Giả sử rằng User1 chỉ sử dụng OPS.op1, User2 chỉ sử dụng OPS.op2 và User3 chỉ sử dụng OPS.op3. Ta nên sử dụng các giao diện: IUser1, IUser2, IUser3. Bằng cách này, User1, User2, User3 không quan tâm khi nào có sự thay đổi đối với OPS.

Dependecy Inversion – Nguyên tắc Nghịch đảo phụ thuộc

“Một hệ thống linh hoạt là hệ thống trong đó các phụ thuộc mã nguồn chỉ gắn với các phần trừu tượng, không phải các cài đặt cụ thể”

Ranh giới kiến ​​trúc tách biệt sự trừu tượng khỏi cài đặt. Luồng điều khiển hướng về phía trừu tượng trong khi các phần code phụ thuộc nghịch đảo với nó. Ta gọi nó là Depenecy Inversion.

SOLID principles in OOP

— English version —

The goal of the principles is the creation of mid-level software structures that:

  • Tolerate change,
  • Are easy to understand, and
  • Are the basis of components that can be used in many software systems.

SOLID Principles (English version)

Single Responsibility Principle

“A module should be responsible to one, and only one, actor.”

“Actor” refer to a group one or more people who require that change.

“A module”, now is just a cohesive set of functions and data structures.
Separating code that supports different actors is the necessity

Open-Closed Principle

“A software artifact should be open for extension but closed for modification.”

The principle takes on even greater significance when we consider the level of architectural components.

Transitive dependencies are a violation of the general principle

Steps to analyse the requirement is to

  • First, seperate responsibility of each steps.
  • Next, organize dependencies to ensure changes to one of those responsiblities do not cause changes in the other.

Liskov Substitution Principle

“Square is not a proper subtype of Rectangle”.

“A simple violation of substitutability, can cause a system’s architecture to be polluted with a significant amount of extra mechanisms.”

Nếu mỗi đối được o1 của tập S, có một đối tượng o2 cua tập T sao cho tất cả chương trình P được xác định theo T. Hành vi của P không đổi khi o1 đuọc thế bằng o2 thì tập S sẽ là tập T.

Interface Segregation Principle

“Depending on something that carries baggage that you
don’t need can cause you troubles that you didn’t expect”.

ISP can be seen as a language issue, rather than an architecture issue.
Actually, applying ISP doesn’t not just reply on languge type, we can avoid unnessary redeployment due to code dependencies.

Let’s assume that User1 uses only OPS.op1, User2 uses only OPS.op2, and User3 uses only OPS.op3. We has to use interfaces: IUser1, IUser2, IUser3, so User1, User2, User3 do not care any change to OPS.

Dependecy Inversion Principle

“A flexible system are those in which source code dependencies refer only to abstractions, not to concretions”.

The architectural boundary seperate abstraction from the concrete. Flow of control is toward the abstract side while code dependencies are inverted against that. We call it Depenecy Inversion.

Reference:

  • Book: Clean Architecture (Robert C. Martin)

Leave a Reply

Related Post