Khi viết mã, điều quan trọng là đảm bảo nó dễ đọc và dễ hiểu. Điều này đặc biệt đúng khi làm việc trong các dự án lớn với nhiều phần khác nhau. Một cách để đảm bảo mã của bạn dễ hiểu là tuân theo các nguyên tắc RẮN.
SOLID là viết tắt của năm nguyên tắc khác nhau:
- Nguyên tắc trách nhiệm duy nhất (SRP)
- Nguyên tắc Mở-Đóng (OCP)
- Nguyên tắc thay thế Liskov (LSP)
- Nguyên tắc phân tách giao diện (ISP)
- Nguyên tắc đảo ngược phụ thuộc (DIP)
Chúng ta hãy xem xét từng nguyên tắc một và xem chúng có thể giúp mã của bạn tốt hơn như thế nào.
Giải thích
Nguyên tắc trách nhiệm duy nhất (SRP)
Nguyên tắc Trách nhiệm Đơn lẻ (SRP) nói rằng mỗi phần mã của bạn chỉ nên có một công việc. Điều này có nghĩa là nếu bạn có một đoạn mã làm nhiều việc, bạn nên chia nó thành các phần nhỏ hơn, mỗi phần có nhiệm vụ riêng.
Ví dụ: hãy tưởng tượng bạn có một đoạn mã theo dõi số lần nhấp vào một nút và cũng hiển thị số lần nhấp trên màn hình. Theo SRP, mã này nên được chia thành hai phần riêng biệt: một phần theo dõi số lần nhấp và phần còn lại hiển thị số lần nhấp trên màn hình.
1 2 3 4 5 6 7 8 | <span class="token comment">// Incorrect way of doing it</span> <span class="token keyword">let</span> clickCount <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handleButtonClick</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> clickCount <span class="token operator">+=</span> <span class="token number">1</span> <span class="token punctuation">;</span> document <span class="token punctuation">.</span> <span class="token function">getElementById</span> <span class="token punctuation">(</span> <span class="token string">"click-count"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> innerHTML <span class="token operator">=</span> clickCount <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 | <span class="token comment">// Correct way of doing it</span> <span class="token keyword">let</span> clickCount <span class="token operator">=</span> <span class="token number">0</span> <span class="token punctuation">;</span> <span class="token keyword">function</span> <span class="token function">handleButtonClick</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> clickCount <span class="token operator">+=</span> <span class="token number">1</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">function</span> <span class="token function">updateClickCount</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> document <span class="token punctuation">.</span> <span class="token function">getElementById</span> <span class="token punctuation">(</span> <span class="token string">"click-count"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> innerHTML <span class="token operator">=</span> clickCount <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
Nguyên tắc Mở-Đóng (OCP)
Nguyên tắc Open-Closed (OCP) nói rằng mã của bạn nên mở để mở rộng nhưng đóng để sửa đổi. Điều này có nghĩa là bạn có thể thêm các tính năng mới vào mã của mình mà không cần thay đổi mã hiện có.
Ví dụ, hãy tưởng tượng bạn có một chương trình có thể cộng hai số với nhau. Theo OCP, bạn sẽ có thể thêm một tính năng mới (chẳng hạn như trừ các số) mà không cần thay đổi mã hiện có để thêm số.
1 2 3 4 5 6 7 8 9 10 | <span class="token comment">// Incorrect way of doing it</span> <span class="token keyword">function</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token comment">// It is not a good idea to change the `add` function to a `subtract` function.</span> <span class="token keyword">function</span> <span class="token function">subtract</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">-</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 | <span class="token comment">// Correct way of doing it</span> <span class="token keyword">class</span> <span class="token class-name">Calculator</span> <span class="token punctuation">{</span> <span class="token keyword">static</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">+</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">static</span> <span class="token function">subtract</span> <span class="token punctuation">(</span> <span class="token parameter">a <span class="token punctuation">,</span> b</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> a <span class="token operator">-</span> b <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Nguyên tắc thay thế Liskov (LSP)
Nguyên tắc thay thế Liskov (LSP) nói rằng bạn sẽ có thể sử dụng một lớp con ở bất cứ nơi nào bạn muốn sử dụng lớp cha. Điều này có nghĩa là lớp con phải là phiên bản “tốt hơn” của lớp cha và không được phá vỡ bất kỳ mã nào sử dụng lớp cha.
Ví dụ, hãy tưởng tượng bạn có một lớp cha tên là “Animal” và một lớp con tên là “Dogs”. Theo LSP, bạn sẽ có thể sử dụng đối tượng “Chó” ở bất cứ đâu bạn sẽ sử dụng đối tượng “Động vật” và mã của bạn vẫn hoạt động bình thường.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <span class="token keyword">class</span> <span class="token class-name">Animals</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">name</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> name <span class="token operator">=</span> name <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">speak</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Animals make noise"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Dogs</span> <span class="token keyword">extends</span> <span class="token class-name">Animals</span> <span class="token punctuation">{</span> <span class="token function">speak</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token string">"Woof"</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> animal <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Animals</span> <span class="token punctuation">(</span> <span class="token string">"Animals"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> animal <span class="token punctuation">.</span> <span class="token function">speak</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// prints "Animals make noise"</span> <span class="token keyword">const</span> dog <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Dogs</span> <span class="token punctuation">(</span> <span class="token string">"Dog"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> dog <span class="token punctuation">.</span> <span class="token function">speak</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// prints "Woof"</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> dog <span class="token keyword">instanceof</span> <span class="token class-name">Animals</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token comment">// prints "true"</span> |
Nguyên tắc phân tách giao diện (ISP)
Nguyên tắc Phân tách Giao diện (ISP) nói rằng bạn không nên ép buộc khách hàng triển khai các giao diện mà họ không sử dụng. Điều này có nghĩa là bạn nên tạo các giao diện nhỏ hơn cho các nhóm chức năng liên quan cụ thể.
Ví dụ: hãy tưởng tượng bạn có một giao diện tên là “Ô tô” có chức năng cho cả lái xe và bay. Theo ISP, nếu bạn có một lớp dành cho ô tô chỉ có thể lái, thì không nên buộc phải thực hiện các chức năng bay từ giao diện “Ô tô”.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token comment">// Incorrect way of doing it</span> <span class="token keyword">interface</span> <span class="token class-name">Automobile</span> <span class="token punctuation">{</span> <span class="token function">drive</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token function">fly</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token keyword">implements</span> <span class="token class-name">Automobile</span> <span class="token punctuation">{</span> <span class="token function">drive</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for driving</span> <span class="token punctuation">}</span> <span class="token function">fly</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for flying (not applicable for cars)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token comment">// Correct way of doing it</span> <span class="token keyword">interface</span> <span class="token class-name">Drivable</span> <span class="token punctuation">{</span> <span class="token function">drive</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">Flyable</span> <span class="token punctuation">{</span> <span class="token function">fly</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token keyword">implements</span> <span class="token class-name">Drivable</span> <span class="token punctuation">{</span> <span class="token function">drive</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for driving</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Nguyên tắc đảo ngược phụ thuộc (DIP)
Nguyên tắc đảo ngược phụ thuộc (DIP) nói rằng các mô-đun cấp cao không nên phụ thuộc vào các mô-đun cấp thấp, nhưng cả hai nên phụ thuộc vào sự trừu tượng. Điều này có nghĩa là mã của bạn không nên phụ thuộc vào các lớp hoặc chức năng cụ thể, mà phải phụ thuộc vào các khái niệm trừu tượng.
Ví dụ: hãy tưởng tượng bạn có một lớp tên là “Xe hơi” phụ thuộc vào một lớp tên là “Động cơ”. Theo DIP, lớp “Xe hơi” không nên phụ thuộc vào lớp “Động cơ” cụ thể, mà phụ thuộc vào sự trừu tượng hóa động cơ là gì.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <span class="token comment">// Incorrect way of doing it</span> <span class="token keyword">class</span> <span class="token class-name">Engine</span> <span class="token punctuation">{</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for starting the engine</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> engine <span class="token operator">:</span> Engine <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> engine <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Engine</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> engine <span class="token punctuation">.</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token comment">// Correct way of doing it</span> <span class="token keyword">interface</span> <span class="token class-name">Engine</span> <span class="token punctuation">{</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">RealEngine</span> <span class="token keyword">implements</span> <span class="token class-name">Engine</span> <span class="token punctuation">{</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for starting the engine</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Car</span> <span class="token punctuation">{</span> <span class="token keyword">private</span> engine <span class="token operator">:</span> Engine <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">engine <span class="token operator">:</span> Engine</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> engine <span class="token operator">=</span> engine <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> engine <span class="token punctuation">.</span> <span class="token function">start</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> car <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Car</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">RealEngine</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Trường hợp sử dụng
1. Quy trình thanh toán website thương mại điện tử
Giả sử chúng ta có một trang web thương mại điện tử nơi khách hàng có thể thêm các mặt hàng vào giỏ hàng của họ và sau đó chuyển đến trang thanh toán. Quá trình thanh toán bao gồm tính toán tổng chi phí của các mặt hàng, áp dụng bất kỳ giảm giá hoặc khuyến mãi nào, sau đó xử lý thanh toán.
Theo Nguyên tắc trách nhiệm duy nhất (SRP), chúng ta nên tách quy trình thanh toán thành các lớp khác nhau, mỗi lớp có trách nhiệm cụ thể của riêng mình. Ví dụ: chúng tôi có thể có lớp Giỏ hàng theo dõi các mặt hàng trong giỏ hàng, lớp Giảm giá áp dụng bất kỳ giảm giá hoặc khuyến mại nào và lớp Thanh toán xử lý quá trình thanh toán.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <span class="token keyword">class</span> <span class="token class-name">Cart</span> <span class="token punctuation">{</span> items <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token function">addItem</span> <span class="token punctuation">(</span> <span class="token parameter">item</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> items <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> item <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">getTotal</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> items <span class="token punctuation">.</span> <span class="token function">reduce</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token parameter">total <span class="token punctuation">,</span> item</span> <span class="token punctuation">)</span> <span class="token operator">=></span> total <span class="token operator">+</span> item <span class="token punctuation">.</span> price <span class="token punctuation">,</span> <span class="token number">0</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Discounts</span> <span class="token punctuation">{</span> <span class="token function">applyDiscount</span> <span class="token punctuation">(</span> <span class="token parameter">total</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> total <span class="token operator">*</span> <span class="token number">0.9</span> <span class="token punctuation">;</span> <span class="token comment">// 10% off</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Payment</span> <span class="token punctuation">{</span> <span class="token function">processPayment</span> <span class="token punctuation">(</span> <span class="token parameter">total</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// code for processing the payment</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Checkout</span> <span class="token punctuation">{</span> cart <span class="token punctuation">;</span> discounts <span class="token punctuation">;</span> payment <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">cart <span class="token punctuation">,</span> discounts <span class="token punctuation">,</span> payment</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> cart <span class="token operator">=</span> cart <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> discounts <span class="token operator">=</span> discounts <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> payment <span class="token operator">=</span> payment <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">processCheckout</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">const</span> total <span class="token operator">=</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> discounts <span class="token punctuation">.</span> <span class="token function">applyDiscount</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> cart <span class="token punctuation">.</span> <span class="token function">getTotal</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> payment <span class="token punctuation">.</span> <span class="token function">processPayment</span> <span class="token punctuation">(</span> total <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> cart <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Cart</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> cart <span class="token punctuation">.</span> <span class="token function">addItem</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">"item1"</span> <span class="token punctuation">,</span> price <span class="token operator">:</span> <span class="token number">20</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> cart <span class="token punctuation">.</span> <span class="token function">addItem</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> name <span class="token operator">:</span> <span class="token string">"item2"</span> <span class="token punctuation">,</span> price <span class="token operator">:</span> <span class="token number">30</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> checkout <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Checkout</span> <span class="token punctuation">(</span> cart <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Discounts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Payment</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> checkout <span class="token punctuation">.</span> <span class="token function">processCheckout</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Trong ví dụ này, mỗi lớp có một trách nhiệm duy nhất: lớp Cart
theo dõi các mặt hàng trong giỏ hàng, lớp Discounts
áp dụng giảm giá, lớp Payment
xử lý thanh toán và lớp Checkout
điều phối quá trình. Điều này làm cho mã dễ bảo trì hơn và dễ hiểu hơn.
2. Ứng dụng thời tiết
Giả sử chúng ta có một ứng dụng thời tiết hiển thị nhiệt độ, độ ẩm và áp suất hiện tại cho một vị trí nhất định. Chúng tôi muốn thêm một tính năng mới hiển thị tốc độ và hướng gió.
Theo Nguyên tắc Đóng-Mở (OCP), chúng tôi có thể thêm tính năng mới này mà không cần sửa đổi mã hiện có hiển thị nhiệt độ, độ ẩm và áp suất.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <span class="token keyword">class</span> <span class="token class-name">WeatherData</span> <span class="token punctuation">{</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">temperature <span class="token punctuation">,</span> humidity <span class="token punctuation">,</span> pressure</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> temperature <span class="token operator">=</span> temperature <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> humidity <span class="token operator">=</span> humidity <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> pressure <span class="token operator">=</span> pressure <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">WeatherDisplay</span> <span class="token punctuation">{</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token parameter">weatherData</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Temperature: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> weatherData <span class="token punctuation">.</span> temperature <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Humidity: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> weatherData <span class="token punctuation">.</span> humidity <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Pressure: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> weatherData <span class="token punctuation">.</span> pressure <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">WindDisplay</span> <span class="token punctuation">{</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token parameter">weatherData</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Wind speed: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> weatherData <span class="token punctuation">.</span> windSpeed <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Wind direction: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token punctuation">(</span> weatherData <span class="token punctuation">,</span> windDirection <span class="token punctuation">)</span> <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">WeatherApp</span> <span class="token punctuation">{</span> weatherData <span class="token punctuation">;</span> weatherDisplay <span class="token punctuation">;</span> windDisplay <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">weatherData</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> weatherData <span class="token operator">=</span> weatherData <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> weatherDisplay <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeatherDisplay</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> windDisplay <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WindDisplay</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">displayWeather</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> weatherDisplay <span class="token punctuation">.</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> weatherData <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> windDisplay <span class="token punctuation">.</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> weatherData <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> weatherData <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeatherData</span> <span class="token punctuation">(</span> <span class="token number">72</span> <span class="token punctuation">,</span> <span class="token number">50</span> <span class="token punctuation">,</span> <span class="token number">1013</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> weatherData <span class="token punctuation">.</span> windSpeed <span class="token operator">=</span> <span class="token number">5</span> <span class="token punctuation">;</span> weatherData <span class="token punctuation">.</span> windDirection <span class="token operator">=</span> <span class="token string">"NW"</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> weatherApp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">WeatherApp</span> <span class="token punctuation">(</span> weatherData <span class="token punctuation">)</span> <span class="token punctuation">;</span> weatherApp <span class="token punctuation">.</span> <span class="token function">displayWeather</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Trong ví dụ này, lớp WeatherApp
mở rộng bằng cách thêm lớp WindDisplay
mới mà không sửa đổi lớp WeatherDisplay
hiện có. Điều này cho phép chúng tôi thêm các tính năng mới vào ứng dụng mà không ảnh hưởng đến mã hiện có.
3. Nhân vật trong game
Giả sử chúng ta có một trò chơi có nhiều loại nhân vật khác nhau, mỗi loại có những khả năng riêng. Chúng tôi muốn thêm một loại nhân vật mới mà không phá vỡ cơ chế trò chơi hiện có.
Theo Nguyên tắc thay thế Liskov (LSP), chúng tôi sẽ có thể sử dụng lớp ký tự mới ở bất cứ nơi nào chúng tôi sẽ sử dụng lớp ký tự gốc và trò chơi vẫn hoạt động bình thường.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token keyword">class</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span> <span class="token function">move</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Character moved"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Warrior</span> <span class="token keyword">extends</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span> <span class="token function">attack</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Warrior attacked"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Mage</span> <span class="token keyword">extends</span> <span class="token class-name">Character</span> <span class="token punctuation">{</span> <span class="token function">castSpell</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Mage cast a spell"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">Paladin</span> <span class="token keyword">extends</span> <span class="token class-name">Warrior</span> <span class="token punctuation">{</span> <span class="token function">heal</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token string">"Paladin healed"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> characters <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token keyword">new</span> <span class="token class-name">Warrior</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Mage</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token class-name">Paladin</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token keyword">for</span> <span class="token punctuation">(</span> <span class="token keyword">let</span> character <span class="token keyword">of</span> characters <span class="token punctuation">)</span> <span class="token punctuation">{</span> character <span class="token punctuation">.</span> <span class="token function">move</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> character <span class="token keyword">instanceof</span> <span class="token class-name">Warrior</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> character <span class="token punctuation">.</span> <span class="token function">attack</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> character <span class="token keyword">instanceof</span> <span class="token class-name">Mage</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> character <span class="token punctuation">.</span> <span class="token function">castSpell</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> character <span class="token keyword">instanceof</span> <span class="token class-name">Paladin</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> character <span class="token punctuation">.</span> <span class="token function">heal</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Trong ví dụ này, lớp Paladin là một lớp con của lớp Chiến binh và nó có khả năng chữa lành vết thương riêng, nhưng nó vẫn thực hiện chính xác phương thức di chuyển từ lớp cha, vì vậy nó có thể được sử dụng ở bất cứ đâu mà đối tượng Character được sử dụng. Điều này cho phép chúng tôi thêm các loại nhân vật mới mà không phá vỡ cơ chế trò chơi hiện có.
4. Ứng dụng trò chuyện
Giả sử chúng ta có một ứng dụng trò chuyện cho phép người dùng gửi tin nhắn và tệp. Chúng tôi muốn tách chức năng gửi tin nhắn và gửi tệp để khách hàng chỉ cần một trong hai tính năng không phải triển khai tính năng còn lại.
Theo Nguyên tắc phân tách giao diện (ISP), chúng ta nên tạo hai giao diện riêng biệt, một giao diện để gửi tin nhắn và một giao diện khác để gửi tệp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token keyword">interface</span> <span class="token class-name">MessageSender</span> <span class="token punctuation">{</span> <span class="token function">sendMessage</span> <span class="token punctuation">(</span> message <span class="token operator">:</span> string <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">interface</span> <span class="token class-name">FileSender</span> <span class="token punctuation">{</span> <span class="token function">sendFile</span> <span class="token punctuation">(</span> file <span class="token operator">:</span> File <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">ChatClient</span> <span class="token keyword">implements</span> <span class="token class-name">MessageSender</span> <span class="token punctuation">{</span> <span class="token function">sendMessage</span> <span class="token punctuation">(</span> message <span class="token operator">:</span> string <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for sending a message</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">FileTransferClient</span> <span class="token keyword">implements</span> <span class="token class-name">FileSender</span> <span class="token punctuation">{</span> <span class="token function">sendFile</span> <span class="token punctuation">(</span> file <span class="token operator">:</span> File <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for sending a file</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">AdvancedChatClient</span> <span class="token keyword">implements</span> <span class="token class-name">MessageSender</span> <span class="token punctuation">,</span> FileSender <span class="token punctuation">{</span> <span class="token function">sendMessage</span> <span class="token punctuation">(</span> message <span class="token operator">:</span> string <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for sending a message</span> <span class="token punctuation">}</span> <span class="token function">sendFile</span> <span class="token punctuation">(</span> file <span class="token operator">:</span> File <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> <span class="token comment">// code for sending a file</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> chatClient <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">ChatClient</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> chatClient <span class="token punctuation">.</span> <span class="token function">sendMessage</span> <span class="token punctuation">(</span> <span class="token string">"Hello!"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> fileTransferClient <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">FileTransferClient</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> fileTransferClient <span class="token punctuation">.</span> <span class="token function">sendFile</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">File</span> <span class="token punctuation">(</span> <span class="token string">"file.txt"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> advancedChatClient <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">AdvancedChatClient</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> advancedChatClient <span class="token punctuation">.</span> <span class="token function">sendMessage</span> <span class="token punctuation">(</span> <span class="token string">"Hello!"</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> advancedChatClient <span class="token punctuation">.</span> <span class="token function">sendFile</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">File</span> <span class="token punctuation">(</span> <span class="token string">"file.txt"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Trong ví dụ này, lớp ChatClient
chỉ triển khai giao diện MessageSender
và không phải triển khai giao diện FileSender
và lớp FileTransferClient
chỉ triển khai giao diện FileSender
và không phải triển khai giao diện MessageSender
. Điều này cho phép khách hàng chỉ triển khai chức năng họ cần, đồng thời giữ cho mã rõ ràng và dễ hiểu.
5. Nền tảng truyền thông xã hội
Giả sử chúng ta có một nền tảng truyền thông xã hội cho phép người dùng đăng cập nhật văn bản và hình ảnh. Chúng tôi muốn thêm một tính năng mới cho phép người dùng đăng cập nhật video mà không thay đổi mã hiện tại để xử lý cập nhật văn bản và hình ảnh.
Theo Nguyên tắc đảo ngược phụ thuộc (DIP), chúng ta nên đảm bảo rằng mã để xử lý các bản cập nhật không phụ thuộc vào các lớp hoặc chức năng cụ thể, mà phụ thuộc vào các khái niệm trừu tượng.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | <span class="token keyword">interface</span> <span class="token class-name">Update</span> <span class="token punctuation">{</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">TextUpdate</span> <span class="token keyword">implements</span> <span class="token class-name">Update</span> <span class="token punctuation">{</span> text <span class="token operator">:</span> string <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">text <span class="token operator">:</span> string</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> text <span class="token operator">=</span> text <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> <span class="token template-string"><span class="token template-punctuation string">`</span> <span class="token string">Text Update: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> text <span class="token interpolation-punctuation punctuation">}</span></span> <span class="token template-punctuation string">`</span></span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">ImageUpdate</span> <span class="token keyword">implements</span> <span class="token class-name">Update</span> <span class="token punctuation">{</span> imageUrl <span class="token operator">:</span> string <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">imageUrl <span class="token operator">:</span> string</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> imageUrl <span class="token operator">=</span> imageUrl <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> Image Update <span class="token operator">:</span> $ <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> imageUrl <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">VideoUpdate</span> <span class="token keyword">implements</span> <span class="token class-name">Update</span> <span class="token punctuation">{</span> videoUrl <span class="token operator">:</span> string <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token parameter">videoUrl <span class="token operator">:</span> string</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> videoUrl <span class="token operator">=</span> videoUrl <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{</span> console <span class="token punctuation">.</span> <span class="token function">log</span> <span class="token punctuation">(</span> Video Update <span class="token operator">:</span> $ <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> videoUrl <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">SocialMediaApp</span> <span class="token punctuation">{</span> updates <span class="token operator">:</span> Update <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token function">constructor</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> updates <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">addUpdate</span> <span class="token punctuation">(</span> <span class="token parameter">update <span class="token operator">:</span> Update</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> updates <span class="token punctuation">.</span> <span class="token function">push</span> <span class="token punctuation">(</span> update <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token function">displayUpdates</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">this</span> <span class="token punctuation">.</span> updates <span class="token punctuation">.</span> <span class="token function">forEach</span> <span class="token punctuation">(</span> <span class="token parameter">update</span> <span class="token operator">=></span> update <span class="token punctuation">.</span> <span class="token function">display</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">const</span> socialMediaApp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">SocialMediaApp</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> socialMediaApp <span class="token punctuation">.</span> <span class="token function">addUpdate</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">TextUpdate</span> <span class="token punctuation">(</span> <span class="token string">"Hello, world!"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> socialMediaApp <span class="token punctuation">.</span> <span class="token function">addUpdate</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">ImageUpdate</span> <span class="token punctuation">(</span> <span class="token string">"image.jpg"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> socialMediaApp <span class="token punctuation">.</span> <span class="token function">addUpdate</span> <span class="token punctuation">(</span> <span class="token keyword">new</span> <span class="token class-name">VideoUpdate</span> <span class="token punctuation">(</span> <span class="token string">"video.mp4"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> socialMediaApp <span class="token punctuation">.</span> <span class="token function">displayUpdates</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Trong ví dụ này, lớp SocialMediaApp
không phụ thuộc vào các lớp cụ thể để xử lý cập nhật văn bản, hình ảnh hoặc video, mà phụ thuộc vào khái niệm trừu tượng của giao diện Update
. Điều này cho phép chúng tôi thêm các loại cập nhật mới (chẳng hạn như cập nhật video) mà không thay đổi mã hiện có để xử lý các cập nhật văn bản và hình ảnh.
Phần kết luận
Các nguyên tắc SOLID là một bộ hướng dẫn giúp các nhà phát triển viết mã rõ ràng, dễ bảo trì và dễ hiểu. Bằng cách tuân theo các nguyên tắc này, các nhà phát triển có thể đảm bảo rằng mã của họ dễ làm việc và có thể dễ dàng mở rộng hoặc sửa đổi trong tương lai. Các nguyên tắc SOLID là: Nguyên tắc trách nhiệm đơn (SRP), Nguyên tắc đóng mở (OCP), Nguyên tắc thay thế Liskov (LSP), Nguyên tắc phân tách giao diện (ISP) và Nguyên tắc đảo ngược phụ thuộc (DIP). Mỗi nguyên tắc đều có lời giải thích, ưu điểm và ví dụ sử dụng trong thế giới thực với các đoạn mã riêng. Điều quan trọng cần lưu ý là các nguyên tắc RẮN không phải là các quy tắc cứng và nhanh, mà là các hướng dẫn chung có thể được áp dụng theo các cách khác nhau, tùy thuộc vào dự án hoặc ứng dụng cụ thể.