SOLID principles Flashcards
What is the DRY principle?
DRY (Do not Repeat Yourself)
- avoid duplication: a piece of data has a single value stored on the system. Don’t store duplicated data
- centralise logic to make it easier to update/test/understand
- write concise, reusable code
What are some violations of the DRY principle?
- storing repeated data across db tables
- storing derived data across db tables
- storing same data at client and server
What are the 5 SOLID principles?
1) Single Responsibility
2) Open Closed principle
3) Liskov substitution principle
4) interface segregation principle
5) Dependency inversion principle
What do the SOLID principles help do?
They are design principles for creating OO code that is likely to have less problems with rigidity, fragility, immobility and viscosity
Explain the first principle of the SOLID principles:
Single responsibility: a class should only have one responsibility
- why? if it has multiple, changes to one responsibility could impact the other
When detecting a breach of the single responsibility principle, what should you look for:
When a class is handling multiple things:
e.g the word processor class is responsible for saving a document, loading a document and spell checking a document, these should be separated into a SpellChecker class and a fileHandler class
What are the benefits of single responsibility?
- Reduces coupling
- easier to test, understand and maintain code
- improves code reusability
- several developers can work on coding classes simultaneously (due to low coupling)
What is the Open Closed principle:
Classes are 1) open for extension and 2) closed for modification
- why? you should be able to add new functionality to a class without altering it’s existing code
How is the open closed principle achieved?
- Through abstraction, abstract classes and interfaces, and dynamic or static polymorphism
(inheritance and overriding methods) - Use the word final in constructors/method definitions when code shouldn’t be modified
When detecting a breach of the open closed principle, what should you look for:
class DiscountCalculator:
def calculate_discount(self, customer_type, amount):
if customer_type == “Regular”:
return amount * 0.05
elif customer_type == “Premium”:
return amount * 0.10
elif customer_type == “VIP”:
return amount * 0.20
else:
return 0
Having if, elif, elif and else that all return different values
- if a new customer_type needs to be added another elif statement is added, this violated the OC principle, because the class should just be extended to add another customer type
What are the benefits of the open closed principle?
- The current code base is kept stable and bug free but allows for future code development
- new functionality can be added without breaking/changing exising working code
- enhanced scalability
What does the final keyword mean?
That a method or class can’t be overridden
What would be the structure for a correct implementation of the open closed principle:
- public interface IcardProvider {
public boolean makePayment(string number)
} - public class cardProviderBase implements IcardProvider { //closed for modification
public final boolean makePayment(string number) {
return number }
}
protected boolean onMakePayment(String number) { //open for extension
return(false)
}
} - public class natwestCardProvider extends CardProviderBase{
protected boolean
onMakePayment(String number) {
return(true);}
}
What are signs that the open closed principle has been breached?
- Adding new if/elif conditions to existing methods to handle new cases.
- Modifying existing classes to add new functionality instead of creating new classes or methods.
What is the Liskov substitution principle:
subclasses must be substitutable for their base classes
- why: subclasses should adhere to the behaviour expected of their parent class
What are the benefits of the liskov principle?
- prevents unexpected behavior in inheritance hierarchies
- improves code reliability
When detecting a breach of the liskov substitution principle, what should you look for:
A subclass that doesn’t have the method of a superclass or doesn’t make use of that method.
e.g. a Class Bird has method fly() is extended by Class Penguin which can’t fly
How can a class the breaches the liskov substitution principle be fixed?
By having the subclass match the superclasses methods or by splitting the superclass into more classes with differing functionality and having the subclass inherit from the correct one
e.g. Class bird should become classes flyingBird and nonFlyingBird and class penguin should then inherit from nonFlyingBird which won’t have method fly()
What is the Interface segregation principle:
a class should not be forced to implement methods of an interface that it doesn’t use
- interfaces should be small and specific to avoid classes implementing unnecessary methods
When detecting a breach of the interface segregation principle, what should you look for:
An interface with lots of methods, and a class implementing the interface and defining the method though it’s irrelevant
e.g a Bird interface having method fly() and a penguin class defining fly when it can’t fly
What are the benefits of the interface segregation principle?
- low coupling
- code flexiblity
- makes classes easier to understand and implement
How can a bad implementation of the interface segregation principle be fixed?
Splitting a large interface into two or more smaller interfaces, so base classes that implement the interface actually require all the methods they need to define
e.g. split Bird interface into nonflyingBird interface with methods eat() and flyingBird interface with methods eat() and fly()
What is the dependency inversion principle:
- high level modules should not depend on low level modules.
- Both should depend on details
- details should depend on abstractions
why: means low and high level modules will communicate through interfaces/abstract classes instead of concrete implementation - if low level modules change, it won’t break high level modules
What are the benefits of dependency inversion principle?
- increases flexibility
- easier to test
- reduces coupling/dependency issues
What does a bad and good implementation of the dependency look like
- Instead of a DatabaseService class directly depending on a concrete class MySQLDatabase
- it should depend on an interface like Database.
- This allows switching to another database with minimal changes.
What is polymorphism?
It allows objects of different types to be treated as instances of the same class through a common interface
What is dynamic polymorphism?
- achieved by method overriding, where a subclass provides it’s own implementation of a method defined in the superclass
- if a method is final it can’t be overridden in the subclass
- implements the open closed principle
What is static polymorphism?
- achieved through method overloading, where classes have multiple methods with the same name but different parameter types or counts
- implements open closed principle
What do the first 3 principles of SOLID focus on and what do the last 2 principles focus on?
- The first 3 principles focus on designing code to stop things going wrong
- the last 2 principles focus on designing code well
What is the top down approach structure for OO design:
Interface
|
abstract sub class
| |
concrete class concrete class