Expand Your Knowledge

SOLID principles - A key in object-oriented programming

SOLID principles are key in object-oriented programming. But what does each principle actually mean, and why are they significant?

๐—ฆ๐—ข๐—Ÿ๐—œ๐—— ๐—ฟ๐—ฒ๐—ฝ๐—ฟ๐—ฒ๐˜€๐—ฒ๐—ป๐˜๐˜€ ๐—ณ๐—ถ๐˜ƒ๐—ฒ ๐—ฝ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ๐˜€ ๐—ผ๐—ณ ๐—ผ๐—ฏ๐—ท๐—ฒ๐—ฐ๐˜-๐—ผ๐—ฟ๐—ถ๐—ฒ๐—ป๐˜๐—ฒ๐—ฑ ๐—ฝ๐—ฟ๐—ผ๐—ด๐—ฟ๐—ฎ๐—บ๐—บ๐—ถ๐—ป๐—ด. Whether or not you use OOP, ๐—ธ๐—ป๐—ผ๐˜„๐—ถ๐—ป๐—ด ๐˜๐—ต๐—ฒ๐˜€๐—ฒ ๐—ฝ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ๐˜€ ๐—ด๐—ถ๐˜ƒ๐—ฒ๐˜€ ๐˜†๐—ผ๐˜‚ ๐—ฎ ๐—น๐—ฒ๐—ป๐˜€ ๐—ถ๐—ป๐˜๐—ผ ๐˜๐—ต๐—ฒ ๐—ณ๐—ผ๐˜‚๐—ป๐—ฑ๐—ฎ๐˜๐—ถ๐—ผ๐—ป๐˜€ ๐—ผ๐—ณ ๐—ฐ๐—น๐—ฒ๐—ฎ๐—ป ๐—ฐ๐—ผ๐—ฑ๐—ฒ which can be applied to many areas of programming.

๐—ฆ โ€” Single Responsibility Principle
๐—ข โ€” Open/Closed Principle
๐—Ÿ โ€” Liskov Substitution Principle
๐—œ โ€” Interface Segregation Principle
๐—— โ€” Dependency Inversion Principle

Letโ€™s break down each principle โ†“

๐Ÿญ. ๐—ฆ๐—ถ๐—ป๐—ด๐—น๐—ฒ ๐—ฅ๐—ฒ๐˜€๐—ฝ๐—ผ๐—ป๐˜€๐—ถ๐—ฏ๐—ถ๐—น๐—ถ๐˜๐˜† ๐—ฃ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ (๐—ฆ๐—ฅ๐—ฃ)

Each unit of code should only have one job or responsibility. A unit can be a class, module, function, or component. This keeps code modular and removes the risk of tight coupling.

๐Ÿฎ. ๐—ข๐—ฝ๐—ฒ๐—ป-๐—–๐—น๐—ผ๐˜€๐—ฒ๐—ฑ ๐—ฃ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ (๐—ข๐—–๐—ฃ)

Units of code should be open for extension but closed for modification. You should be able to extend functionality with additional code rather than modifying existing ones. This principle can be applied to component-based systems such as a React frontend.

๐Ÿฏ. ๐—Ÿ๐—ถ๐˜€๐—ธ๐—ผ๐˜ƒ ๐—ฆ๐˜‚๐—ฏ๐˜€๐˜๐—ถ๐˜๐˜‚๐˜๐—ถ๐—ผ๐—ป ๐—ฃ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ (๐—Ÿ๐—ฆ๐—ฃ)

You should be able to substitute objects a of base class with objects of its subclass without altering the โ€˜correctnessโ€™ of the program.

An example of this is with a Bird base class. You might assume that it should have a โ€˜flyโ€™ method. But what about the birds that canโ€™t fly? Like a Penguin. In this example, having a โ€˜flyโ€™ method in the Bird class would violate LSP.

๐Ÿฐ. ๐—œ๐—ป๐˜๐—ฒ๐—ฟ๐—ณ๐—ฎ๐—ฐ๐—ฒ ๐—ฆ๐—ฒ๐—ด๐—ฟ๐—ฒ๐—ด๐—ฎ๐˜๐—ถ๐—ผ๐—ป ๐—ฃ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ (๐—œ๐—ฆ๐—ฃ)

Provide multiple interfaces with specific responsibilities rather than a small set of general-purpose interfaces. Clients shouldnโ€™t need to know about the methods & properties that don't relate to their use case.

Complexity โ†“
Code flexibility โ†‘

๐Ÿฑ. ๐——๐—ฒ๐—ฝ๐—ฒ๐—ป๐—ฑ๐—ฒ๐—ป๐—ฐ๐˜† ๐—œ๐—ป๐˜ƒ๐—ฒ๐—ฟ๐˜€๐—ถ๐—ผ๐—ป ๐—ฃ๐—ฟ๐—ถ๐—ป๐—ฐ๐—ถ๐—ฝ๐—น๐—ฒ (๐——๐—œ๐—ฃ)

You should depend on abstractions, not on concrete classes. Use abstractions to decouple dependencies between different parts of the systems. Direct calls between units of code shouldnโ€™t be done, instead interfaces or abstractions should be used.