In software development, certain concepts shape how we think, design, and build software. Among these are Object-Oriented Programming (OOP) and SOLID principles. This cheat sheet provides both newcomers and professionals with a clear and quick summary and practical insights into those concepts.
This article is just an overview; it is not a practical toolkit or a theoretical reference. It intends merely to introduce you to the topic in a simple way or to refresh your knowledge about it.
Object-Oriented Programming (OOP)
OOP forms the backbone of modern software development. It's not merely a programming style but a paradigm that offers a structured approach to creating modular and reusable code.
Concept | Example |
---|---|
Encapsulation is the practice of keeping fields within a class private, then providing access to them via public methods. It's a protective barrier that keeps the data and code safe within the class itself, so that code outside of the class cannot access or change it. | |
Abstraction hides the complex implementations, and exposing only the necessary parts. It defines the necessary aspects of an entity without involving the background details or explanations. | class Shape(ABC): @abstractmethod def area(self): pass @abstractmethod def perimeter(self): pass |
Inheritance is a way to form new classes using pre defined classes. The new classes, known as derived classes, inherit attributes and methods from the pre-existing classes, which are referred to as base classes. This allows for creating a class hierarchy and for the use of polymorphism. | |
Polymorphism gives a way to use a class exactly like its parent so there's no confusion with mixing types. However, each child class can implement its own methods. This means that a child class can override or extend the functionality of a parent class to provide a specific implementation of a method that is already provided by one of its parent classes. |
class Animal: def speak(self): pass class Dog(Animal): def speak(self): return "Woof!" class Cat(Animal): def speak(self): return "Meow!" def make_sound(animal): print(animal.speak()) # The make_sound function can call the speak method on any Animal, although they have different implementations. |
Class/Object A class is a blueprint for creating objects. It encapsulates data for the object and methods to manipulate that data. An Object is an instance of a class. it has state (attributes) and behavior (methods). | # Define a class Car class Car: def __init__(self, make, model): self.make = make self.model = model def display_info(self): print("{self.make} {self.model}") # Create objects of the Car class car1 = Car("Toyota", "Corolla") car2 = Car("Honda", "Civic") # car objects have car class blueprints (make, model and display_info()) |
SOLID Principles
SOLID is the acronym for 5 principles introduced by Robert C. Martin. They are a set of guidelines for OOP design that promote more scalable, robust, and maintainable code.
Single Responsibility Principle (SRP):
Ensures that a class encapsulates only the responsibilities it should, having one reason to change.
Example: A User class should only handle data and behavior related to a user and not include functionality to persist user data to a database. That should be handled by a separate class, perhaps a UserRepository.
Open/Closed Principle (OCP):
Classes should be open for extension but closed for modification. This often involves using abstract classes or interfaces, allowing subclasses to extend their behavior without modifying the parent class.
Example: A PaymentProcessor interface can be extended by CreditCardPaymentProcessor and PaypalPaymentProcessor without altering the interface or other implementations.
Liskov Substitution Principle (LSP):
Subtypes must be substitutable for their base types without altering the correctness of the program.
Example: If Bird is a subclass of Animal, then wherever Animal is expected, a Bird should be able to substitute without issue.
Interface Segregation Principle (ISP):
Clients should not be forced to depend on interfaces they do not use. This principle leads to smaller, more focused interfaces rather than large, general-purpose ones.
Example: Instead of one large Worker interface with many methods, have a Workable interface, a Eatable interface, etc., so classes like RobotWorker don't need to implement eat.
Dependency Inversion Principle (DIP):
High-level modules should not depend on low-level modules but should depend on abstractions. This often involves using encapsulation to hide the implementation details of classes.
Example: A ReportGenerator should not directly instantiate a PDFExporter but rather depend on an IExporter interface. The specific implementation can be injected, often using dependency injection.
0 Comments