SOLID คือชุดของหลักการออกแบบ 5 ข้อในวิศวกรรมซอฟต์แวร์ที่ช่วยให้นักพัฒนาสร้างระบบซอฟต์แวร์ที่บำรุงรักษาได้ ขยายได้ และทนทานมากขึ้น SOLID ย่อมาจาก S: Single Responsibility Principle, O: Open/Closed Principle, L: Liskov Substitution Principle, I: Interface Segregation Principle และ D: Dependency Inversion Principle หลักการแต่ละข้อมุ่งเน้นไปที่แง่มุมที่แตกต่างกันของการออกแบบซอฟต์แวร์ แต่ทั้งหมดเชื่อมโยงกันและเสริมซึ่งกันและกัน
(1) Single responsibility principle คือการที่คลาสควรจะรับผิดชอบเพียงอย่างเดียวและทำให้ดี เพราะหากคลาสต้องรับผิดชอบหลายอย่าง การเปลี่ยนแปลงในความรับผิดชอบหนึ่งอาจจะส่งผลกระทบกับความรับผิดชอบอื่นทำให้การบำรุงรักษา ทดสอบ และขยายความสามารถทำได้ยาก การทำตามแนวทางนี้จะช่วยให้โปรแกรมง่ายต่อการทำความเข้าใจ บำรุงรักษา แก้ไข และทดสอบ และยังส่งเสริมการลดความผูกพันระหว่างคลาส มีความยืดหยุ่นและรองรับการเปลี่ยนแปลง
(2) Open/closed principle คือการที่เราสามารถเพิ่มความสามารถของคลาส (หรือโมดูล หรือฟังก์ชั่น) ได้โดยที่ไม่ต้องแก้ไขโปรแกรมเดิม โดยที่โปรแกรมใหม่สามารถใช้งานและทำงานร่วมกับโปรแกรมเดิมได้ และโปรแกรมเดิมยังคงมีพฤติกรรมเหมือนเดิม แนวทางนี้ช่วยให้โปรแกรมยืดหยุ่นและบำรุงรักษาง่าย เพราะสามารถขยายความสามารถได้โดยไม่กระทบ
ฟังก์ชั่นเดิม และยังส่งเสริมการนำโปรแกรมเดิมมาใช้ใหม่ วิธีการตามแนวทางนี้คือการใช้คลาสแบบอินเตอร์เฟสและคลาสแบบแอบแสตรก ดังนั้นฟังก์ชั่นใหม่สามารถเพิ่มได้โดยการสร้างคลาสที่สืบทอดจากคลาสแบบแอบแสตรกหรืออิมพลีเมนท์การใช้คลาสแบบอินเตอร์เฟส
(3) Liskov substitution principle คือการที่คลาสลูกที่สืบทอดจากคลาสแม่ต้องสามารถถูกใช้แทนที่คลาสแม่ได้โดยไม่ทำให้เกิดข้อผิดพลาดหรือเกิดพฤติกรรมที่ไม่คาดคิด นั่นคือหากโปรแกรมเคยเรียกใช้คลาสแม่แล้วเปลี่ยนมาใช้คลาสลูก คลาสลูกจะต้องทำงานหรือมีพฤติกรรมเช่นเดียวกับคลาสแม่และไม่ทำให้โปรแกรมที่มาเรียกใช้ทำงานต่างไปจากเดิม วิธีการตามแนวทางนี้คือการสร้างคลาสแบบเจเนริคซึ่งทำให้โปรแกรมสามารถปรับเปลี่ยนจากการใช้คลาสแม่มาใช้คลาสลูกเพื่อให้มีพฤติกรรมที่แตกต่างออกโดยไม่ต้องแก้ไขโปรแกรม และยังช่วยให้ทดสอบได้ง่ายเพราะสามารถเตรียมการทดสอบกับคลาสแม่แล้วค่อยเปลี่ยนเป็นคลาสลูกตามเงื่อนไขที่ต้องการ
(4) Interface segregation principle คือการที่คลาสต้องไม่ถูกบังคับให้ใช้คลาสแบบอินเตอร์เฟสที่ไม่ต้องการ ดังนั้นเราต้องออกแบบคลาสอินเตอร์เฟสให้ประกอบด้วยฟิลด์และเมธอดที่ทำงานในเรื่องเดียวกันเท่านั้น ซึ่งจะทำให้คลาสสามารถเลือกใช้คลาสแบบอินเตอร์เฟสที่ต้องการเท่านั้น ทำให้ได้คลาสแบบอินเตอร์เฟสที่มีขนาดเล็ก ลดการผูกพันระหว่างคลาส มีความยืดหยุ่น รองรับการเปลี่ยนแปลง ช่วยให้ทดสอบได้ง่ายเพราะออบเจกต์ที่ใช้ในการทดสอบจะไม่ซับซ้อน บำรุงรักษาง่าย สนับสนุนการแบ่งส่วนโปรแกรม และสนับสนุนการนำรหัสโปรแกรมเดิมมาใช้ใหม่
(5) Dependency inversion principle คือการลดความผูกพันระหว่างคลาสโดยให้คลาสติดต่อกันผ่านคลาสแบบแอบแสตรกหรือคลาสแบบอินเตอร์เฟส ดังนั้นแทนที่คลาส A จะเรียกใช้งานคลาส B ที่เป็นอีกโปรแกรมหนึ่งโดยตรงก็ให้สร้างคลาสแบบอินเตอร์เฟสหรือคลาสแบบแอบแสตรกขึ้นมา และให้คลาส B สืบทอดหรือใช้อินเตอร์เฟส โดยคลาส A จะเรียกใช้ผ่านคลาสแบบแอบแสตรกหรือคลาสแบบอินเตอร์เฟส เช่น ถ้าเราต้องการสร้างระบบชำระเงิน เรามีคลาส PaymentProcess ที่ทำหน้าที่ชำระเงินซึ่งเรียกใช้คลาส PaymentGateway ที่เป็นโปรแกรมทำหน้าที่ชำระเงินผ่าน Paypal หากทำตามแนวทางนี้คลาส PaymentGateway ต้องเป็นคลาสแบบแอบแสตรกและสร้างคลาส PaypalGateway ซึ่งสืบทอดจากคลาส PaymentGateway อีกที ซึ่งในอนาคตเราสามารถเพิ่มคลาสเกตเวย์แบบอื่นๆได้โดยที่ไม่กระทบกับคลาส PaymentProcess ทำให้ลดการผูกพันระหว่างคลาส มีความยืดหยุ่น รองรับการเปลี่ยนแปลง ทดสอบได้ง่าย บำรุงรักษาง่าย สนับสนุนการแบ่งส่วนโปรแกรม และสนับสนุนการนำรหัสโปรแกรมเดิมมาใช้ใหม่