SOLID là gì? Ứng dụng SOLID để trở xây dựng thương hiệu trình viên chuyên nghiệp | TopDev

Phần mềm được xem là phải chăng lúc lúc nó có kiến trúc phải chăng. Kiến trúc phần mềm tương tự động như móng nhà, móng yếu nhà sẽ ko vững. Để viết được phần mềm phải chăng bạn nên học siêu nhiều, điều trước tiên bạn cần biết là SOLID.

SOLID ra đời như thế nào?

Lập trình hướng đối tượng (object oriented programming – OOP) là 1 trong những mô hình lập trình được dùng nhiều nhất. Những tính chất đặc biệt làm cho việc hướng đối tượng trở nên hiệu quả đấy là:

  • Tính trừu tượng (abstraction): Tạo ra những lớp trừu tượng mô hình hoá những đối tượng trong thế giới thực.
  • Tính đóng gói (Encapsulation): Những thực thể của lớp trừu tượng có những giá trị thuộc tính biệt lập.
  • Tính kế thừa (Inheritance): Những đối tượng có thể dễ dàng kế thừa và mở rộng lẫn nhau.
  • Tính đa hình (Polymorphism): Có thể thực hành 1 hành động đơn theo nhiều phương pháp thức khác nhau tuỳ theo loại đối tượng cụ thể đang được gọi.

Những tính chất đặc biệt này của OOP giúp chúng ta xây dựng được những chương trình giải quyết được nhiều vấn đề cụ thể khác nhau trong thế giới thực. Gần như lập trình viên đều đã biết những tính chất này của OOP, nhưng phương pháp thức để phối hợp những tính chất này sở hữu nhau để nâng cao hiệu quả của ứng dụng thì ko nên ai cũng nắm được. 1 trong những chỉ dẫn để giúp chúng ta dùng được OOP hiệu quả hơn đấy là nguyên tắc SOLID.

SOLID là gì?

SOLID là viết tắt của 5 chữ dòng đầu trong 5 nguyên tắc thiết kế hướng đối tượng. Giúp cho lập trình viên viết ra những đoạn code dễ đọc, dễ hiểu, dễ keep. Nó được đưa ra bởi Robert C. Martin và Michael Feathers. 5 nguyên tắc đấy bao gồm:

  • Single accountability priciple (SRP)
  • Open/Closed precept (OCP)
  • Liskov substitution principe (LSP)
  • Interface segregation precept (ISP)
  • Dependency inversion precept (DIP)

Single accountability priciple

Nội dung:

Từng lớp chỉ nên chịu trách nhiệm về 1 nhiệm vụ cụ thể nào đấy mà thôi.

Nguyên lý trước tiên ứng sở hữu chữ S trong SOLID, có ý nghĩa là 1 class chỉ nên giữ 1 trách nhiệm duy nhất. 1 class có quá nhiều chức năng sẽ trở nên cồng kềnh và trở nên khó đọc, khó keep. Mà đối sở hữu ngành IT việc requirement thay đổi đổi, cần thêm sửa chức năng là siêu bình thường, nên việc code trong sáng, dễ đọc dễ hiểu là siêu cần thiết.

Dí dụ: Hình dung rằng viên chức của 1 đơn vị phần mềm cần nên làm cho 1 trong 3 việc sau đây: lập trình phần mềm (developer), đánh giá phần mềm (tester), bán phần mềm (salesman). Từng viên chức sẽ có 1 chức vụ và dựa vào chức vụ sẽ làm cho công việc tương ứng. Lúc đấy bạn có nên thiết kế lớp “Worker” sở hữu thuộc tính “place” và 3 phương thức developSoftware(), testSoftware() và saleSoftware() ko?

class Worker { string place; perform developSoftware(){}; perform testSoftware(){}; perform saleSoftware(){}; }

Câu trả lời là KHÔNG. Thử hình dung ví dụ có thêm 1 chức vụ nữa là quản lí nhân sự, ta sẽ nên sửa lại lớp “Worker”, thêm phương thức new vào sao? Ví dụ có thêm 10 chức vụ nữa thì sao? Lúc đấy những đối tượng được tạo ra sẽ dư thừa siêu nhiều phương thức: Developer thì đâu cần dùng hàm testSoftware() và saleSoftware() đúng ko nào, lỡ could dùng lầm phương thức cũng sẽ gây hậu quả khôn lường.

Xem Thêm  Tìm hiểu costume code là gì | Sen Tây Hồ

Ứng dụng nguyên tắc Single Accountability: từng lớp 1 trách nhiệm. Ta sẽ tạo 1 lớp trừu tượng là “Worker” có phương thức là working(), từ đây bạn kế thừa ra 3 lớp cụ thể là Developer, Tester và Salesman. Tại từng lớp này bạn sẽ implement phương thức working() cụ thể tuy theo nhiệm vụ của từng người. Lúc đấy chúng ta sẽ bị tình trạng dùng nhầm phương thức nữa.

Open/Closed precept

Nội dung:

Ko được sửa đổi 1 Class có sẵn, nhưng có thể mở rộng bằng kế thừa.

Nguyên lý thứ 2 ứng sở hữu chữ O trong SOLID.

Theo nguyên lý này, từng lúc ta muốn thêm chức năng cho chương trình, chúng ta nên viết class new mở rộng class cũ (bằng phương pháp kế thừa hoặc sở hữu class cũ) chứ ko nên sửa đổi class cũ. Việc này dẫn tới tình trạng phát sinh nhiều class, nhưng chúng ta sẽ ko cần nên take a look at lại những class cũ nữa, mà chỉ tập trung vào take a look at những class new, nơi chứa những chức năng new.

Thông thường việc mở rộng thêm chức năng thì nên viết thêm code, vậy để thiết kế ra 1 module có thể dễ dàng mở rộng nhưng lại hạn chế sửa đổi code ta cần làm cho gì. Phương pháp giải quyết là tách những phần dễ thay đổi đổi ra khỏi phần khó thay đổi đổi mà vẫn đảm bảo ko tác động tới phần còn lại.

Dí dụ:

  • Đặt vấn đề: Ta cần 1 lớp đảm nhận việc kết nối tới CSDL. Thiết kế ban đầu chỉ có SQL Server và MySQL. Thiết kế ban đầu có dạng như sau:

class ConnectionManager { public perform doConnection(Object $connection) { if($connection instanceof SqlServer) { //join with SqlServer } elseif($connection instanceof MySql) { //join with MySql } } }

Tiếp theo đề nghị đặt ra nên kết nối thêm tới Oracle và 1 vài hệ CSDL khác. Để thêm chức năng ta nên thêm vào code những khối esleif khác, việc này làm cho code cồng kềnh và khó quản lý hơn.

  • Giải pháp:
    • Ứng dụng Summary thiết kế lại những lớp SqlServer, MySql, Oracle…
    • Những lớp này đều có chung nhiệm vụ tạo kết nối tới csdl tương ứng có thể gọi chung là Connection.
    • Phương pháp thức kết nối tới csdl thay đổi đổi tùy thuộc} thuộc vào từng loại kết nối nhưng có thể gọi chung là doConect.
    • Vậy ta có lớp cơ sở Connection có phương thức doConnect, những lớp cụ thể là SqlServer, MySql, Oracle… kế thừa từ Connection và overwrite lại phương thức doConnect yêu thích sở hữu lớp đấy.

Thiết kế sau thời điểm làm cho lại có dạng như sau:

summary class Connection() { public summary perform doConnect(); } class SqlServer extends Connection { public perform doConnect() { //join with SqlServer } } class MySql extends Connection { public perform doConnect() { //join with MySql } } class ConnectionManager { public perform doConnection(Connection $connection) { //one thing //…………….. //connection $connection->doConnect(); } }

Xem Thêm  Chơi some là gì? Những tư thế chơi some giúp nâng cao khoái cảm

Sở hữu thiết kế này lúc cần kết nối tới 1 loại csdl new chỉ cần thêm 1 lớp new kế thừa Connection mà ko cần sửa đổi code của lớp ConnectionManager, điều này thỏa mãn 2 điều kiện của nguyên lý OCP.

Liskov substitution precept

Nội dung:

Những đối tượng (occasion) kiểu class con có thể thay đổi thế những đối tượng kiểu class cha mà ko gây ra lỗi.

Nguyên tắc thứ 3, ứng sở hữu chữ L trong SOLID.

SOLID là gì? Áp dụng SOLID để trở thành lập trình viên giỏi
Minh hoạ 1 trường hợp vi phạm nguyên tắc Liskov substitution. Ví dụ thiết kế lớp như thế này, thì lớp CleanerStaff sẽ dùng được hàm checkAttendance(), mà điều này là ko đúng, nên đây sẽ là 1 kiểu thiết kế sai nguyên tắc.

Quay trở lại thí dụ lớp Emloyee trong phần 1, ta giả sử có đơn vị sẽ điểm danh vào từng buổi sáng, và chỉ có những viên chức thuộc biên chế chính thức new được phép điểm danh. Ta bổ sung phương thức checkAttendance() vào lớp Worker.

Hình dung có 1 trường hợp sau: đơn vị thuê 1 viên chức lao công để làm cho vệ sinh văn phòng, dù rằng là 1 người làm cho việc cho đơn vị nhưng do ko được cấp số ID nên ko được xem là 1 viên chức bình thường, mà chỉ là 1 viên chức thời vụ, do đấy sẽ ko được điểm danh.

Nguyên tắc này bảo rằng: Ví dụ chúng ta tạo ra 1 lớp CleanerStaff kế thừa từ lớp Worker, và implement hàm working() cho lớp này, thì mọi thứ đều ổn, tuy nhiên lớp new này cũng lại có hàm checkAttendance() để điểm danh, mà như thế là sai quy định dẫn tới chương trình bị lỗi. Như vậy, thiết kế lớp CleanerStaff kế thừa từ lớp Worker là ko được phép.

Có nhiều phương pháp để giải quyết vấn đề này thí dụ như tách hàm checkAttendance() ra 1 interface riêng và chỉ cho những lớp Developer, Tester và Salesman implements interface này.

Interface segregation precept

Nội dung:

Thay thế vì dùng 1 interface lớn, ta nên tách thành nhiều interface bé, sở hữu nhiều phần đích cụ thể.

Nguyên lý này siêu dễ hiểu. Hãy tưởng tượng chúng ta có 1 interface lớn, khoảng 100 strategies. Việc implements sẽ siêu vất vả vì những class impliment interface này sẽ yêu cầu} nên nên thực thi toàn bộ những technique của interface. Bên cạnh ra còn có thể dư thừa vì 1 class ko cần dùng hết 100 technique. Lúc tách interface ra thành nhiều interface bé, gồm những technique liên quan tới nhau, việc implement và quản lý sẽ dễ hơn.

Dí dụ:

Chúng ta có 1 interface Animal như sau:

interface Animal { void eat(); void run(); void fly(); }

Chúng ta có 2 class Canine và Snake implement interface Animal. Nhưng thực vô lý, Canine thì làm cho sao có thể fly(), cũng như Snake ko thể nào run() được? Thay thế vào đấy, chúng ta nên tách thành 3 interface như thế này:

interface Animal { void eat(); } interface RunnableAnimal extends Animal { void run(); } interface FlyableAnimal extends Animal { void fly(); }

Dependency inversion precept

Nội dung:

1.Những module cấp cao ko nên phụ thuộc vào những modules cấp thấp. Cả 2 nên phụ thuộc vào abstraction. 2.Interface (abstraction) ko nên phụ thuộc vào chi tiết, mà ngược lại (Những class giao tiếp sở hữu nhau thông qua interface (abstraction), ko nên thông qua implementation.)

Xem Thêm  Product Placement là gì? Thí dụ về Product Placement

Có thể hiểu nguyên lí này như sau: những thành phần trong 1 chương trình chỉ nên phụ thuộc vào những dòng trừu tượng (abstraction). Những thành phần trừu tượng ko nên phụ thuộc vào những thành phần mang trong mình tính cụ thể mà nên ngược lại.

Những dòng trừu tượng (abstraction) là những dòng ít thay đổi đổi và biến động, nó tập hợp những đặc tính chung nhất của những dòng cụ thể. Những dòng cụ thể dù khác nhau thế nào đi nữa đều tuân theo những quy tắc chung mà dòng trừu tượng đã định ra. Việc phụ thuộc vào dòng trừu tượng sẽ giúp chương trình linh động và thích ứng phải chăng sở hữu những sự thay đổi đổi diễn ra liên tục.

Dí dụ:

Lấy thí dụ về ổ cứng của máy tính, bạn có thể dùng loại ổ cứng thể rắn SSD đời new để chạy cho nhanh, tuy nhiên cũng có thể dùng ổ đĩa quay HDD thông thường. Nhà chế tạo Mainboard ko thể nào biết bạn sẽ dùng ổ SSD hay loại HDD đĩa quay thông thường. Tuy nhiên họ sẽ luôn đảm bảo rằng bạn có thể dùng bất cứ thứ gì bạn muốn, miễn là ổ đĩa cứng đấy nên có chuẩn giao tiếp SATA để có thể gắn được vào bo ổ chủ. Tại đây chuẩn giao tiếp SATA chính là interface, còn SSD hay HDD đĩa quay là implementation cụ thể.

Trong lúc lập trình cũng vậy, lúc vận dụng nguyên lý này, trên những lớp trừu tượng cấp cao, ta thường dùng interface nhiều hơn thay đổi vì 1 kiểu kế thừa cụ thể. Dí dụ, để kết nối tới Database, ta thường thiết kế lớp trừu tượng DataAccess có những phương thức phương thức chung như save(), get(), … Tiếp theo tùy thuộc} vào việc dùng loại DBMS nào (vd: MySql, MongoDB, …) mà ta kế thừa và implement những phương thức này. Tính chất đa hình của OOP được vận dụng siêu nhiều trong nguyên lý này.

Tổng kết

SOLID là 5 nguyên tắc cơ bản trong việc thiết kế phần mềm. Nó giúp chúng ta tổ chức sắp xếp những perform, technique, class 1 phương pháp chính xác hơn. Khiến sao để kết nối những thành phần, module sở hữu nhau.

Rõ ràng, dễ hiểu

Teamwork là điều ko thể giảm thiểu trong lập trình. Ứng dụng SOLID vào công việc bạn sẽ tạo ra những hàm phải chăng, dễ hiểu hơn. Giúp cho bạn và đồng nghiệp đọc hiểu code của nhau phải chăng hơn.

Dễ thay đổi đổi

SOLID giúp tạo ra những module, class rõ ràng, ổ lạc, mang trong mình tính độc lập cao. Do vậy lúc có sự đề nghị thay đổi đổi, mở rộng từ khách hàng, ta cũng ko tốn quá nhiều công sức để thực hành việc thay đổi đổi.

Tái dùng

SOLID làm cho những lập trình viên suy nghĩ nhiều hơn về phương pháp viết phần mềm, do vậy code viết ra sẽ ổ lạc, dễ hiểu, dễ dùng.

Nguồn tham khảo:

  • Những dòng code vui
  • Kipalog

Tham khảo thêm những vùng tuyển dụng lập trình it lương cao nhất tại Topdev