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.
What is one of the most important benefits of dependency injection?
Testability
What should you do with extra responsibilities that don’t fit with the ‘Single Reponsibility’ paradigm?
Delegate to other objects
What does Meyers’ Open / Closed principle state?
That once an object has been completed, it may only be modified to fix bugs, and cannot be modified to add new features.
In Meyers’ description of the Open / Closed principle, how would new features be added to an object?
Through inheritance (Open for extension).
What does the Polymorphic interpretation of Open / Closed state?
Once solidified, the API of a class is set, but classes inheriting from that class may implement that API in anyway they choose.
Which is the more common interpretation of Open / Closed principle, Meyer or Polymorphic.
The polymorphic interpretation - i.e. that once the API is set, classes that inherit from that class may implement that API in anyway they choose.
Objects B and C inherit from A. Swapping B and C with A does not affect the way the program runs in anyway - what principle of Solid does this conform to?
The Liskov principle - that any object of the same type should be interchangeable without affecting the correctness of the program.
Given the need to develop a database class, why would the Interface Segregation principle suggest that it be pertinent to add transactions to a second interface?
Because not all databases are transaction based, and if it were added to the main base class - then databases that don’t support transactions would have to implement that interface.