SOLID Principles Flashcards
What does the S stand for in SOLID?
Single Responsibility Principle
Classes and objects should only have one job
What does the O stand for in SOLID?
The Open/Closed Principle
Objects should be open to extension, but closed to modification
What does the L stand for in SOLID?
Liskov Substitution principle
Objects of the same type should be interchangeable
What does the I stand for in SOLID?
Interface Segregation
Small compact interfaces are preferable to ‘God Objects’.
What does the D stand for in SOLID?
Dependency Inversion
Applications should depend on Abstractions not concrete instances of an object.
Would connecting to a database in order to post a tweet be considered two responsibilities in a PostTweet object?
Yes - the database connection task should be abstracted.
Would the following code be a correct way to remove the responsibility of connecting to a database?
protected function getConnection()
{
return DatabaseLayer::getConnection();
}
Yes - but it could be improved even further by using dependency injection. This at least abstracts away the act of connecting - and allows for mocks and testing.
What is one of the most important tools in the PHP object model for implementing the ‘O’ part of solid (Open / Closed principle)?
Interfaces - these allow the creation of solidified and defined interfaces for creating objects when those objects have similar behaviours but different internals.
What does the Liskov substitution principle state?
That we should be able to swap objects of the same type without changing the correctness of the program.
Interfaces allow us to enforce inputs in PHP, what can we use to enforce outputs?
There are no features built into PHP that enforce outputs - this is why the Liskov principle is important (i.e. we must enforce this ourselves in the design).
What PHP features should we use to help enforce the Liskov principle?
Effective comments and type hinting.
If an object has more than 5-7 methods, what could this indicate?
It has too many responsibilities, and therefore could do with a refactor.
If you find yourself building an interface that not all objects can honor (i.e. you have to implement a stub for that method, but it is empty) what does this indicate?
That you should break your interfaces down into multiple interfaces.
How do you implement multiple interfaces?
class MyClass implements IMyInterface1, IMyInterface2 { }
If it doesn’t make sense to use multiple interfaces (to deal with objects that may have an additional method that others don’t), what is another way of implementing this without violating the Interface Segregation principle?
Use traits - this allows those objects that need to use an extra method to have the method - but doesn’t require the interface to expose a method that not all objects will use.
Why can we simply use a method of an injected object without being concerned whether it exists?
Because if we have followed the O and the I principle, we should be using type hinting and interfaces to inject a dependency. This means the interface is consistent and guaranteed, and we can rely on the abstraction.