User:Jeroen De Dauw/Single Responsibility Principle
From semantic-mediawiki.org
< Jeroen De Dauw
Jeroen De DauwUser:Jeroen De Dauw/Single Responsibility Principle
Jump to:navigation, search
Loading...
The single responsibility principle
YESThe S in SOLID
The first of the first 5 principles
- An object should have one responsibility
- The reponsibility should be entirely encapsulated by this object
The single responsibility principle
YESThe single responsibility principle
YESThe single responsibility principle
YESclass MapsLocation { protected $latitude; protected $longitude; // ... protected $address; protected $isValid; protected $icon; protected $group; // ... protected $format; protected $directional; // ... public function setCoordinates( $coordinates ) { // parse } public function setAddress( $address, $asActualLocation = true ) { // geocode } public function __construct( $coordsOrAddress = null, $format = Maps_COORDS_FLOAT, $directional = false, $separator = ',' ) { // ... } // ... }
The single responsibility principle
YESclass MapsLocation { // The values representing a geographical location protected $latitude; protected $longitude; // ... // Alternatively an "address", which might or might not be "valid" protected $address; protected $isValid; // Information on how the location is used in a map protected $icon; protected $group; // ... // Information on how the location should be formatted protected $format; protected $directional; // ... }
- Clear violation of SRP
The single responsibility principle
YESThe problems with violating SRP
- Will need changes for more then one reason
The single responsibility principle
YESThe problems with violating SRP
- Harder to understand
- Because ...
The single responsibility principle
YESThe problems with violating SRP
- Complexity increases
class MapsLocation { public function setCoordinates( $coordinates ) { // parse } public function setAddress( $address, $asActualLocation = true ) { // geocode } public function __construct( $coordsOrAddress = null, $format = Maps_COORDS_FLOAT, $directional = false, $separator = ',' ) { // ... } // ... }
- Harder to understand
- More bugs
The single responsibility principle
YESThe problems with violating SRP
- Harder to re-use, badly segregated interface
The single responsibility principle
YESValue objects and service objects
- An object either represents a value or provides a service
- Mixing both is particularly bad
The single responsibility principle
YESValue objects
- Simple
- Easy to construct
- Rarely mocked
- Constructed by business logic
- Typically no interface
The single responsibility principle
YESService objects
- Often less easy to understand, particularly internals
- Tend to be hard to construct
- Often mocked
- Injected as dependencies
- Often implement (an) interface(s)
The single responsibility principle
YESThe story of EntityId
Or how I learned to stop worrying and love the SRP
- Mainly about EntityId parsing
The single responsibility principle
YESThe story of EntityId
Step 0: Id parsing code through the codebase
- Not all doing the exact same thing
- Everything procedural
- Static
- Global state
The single responsibility principle
YESThe story of EntityId
Step 1: Utils to the rescue!
- Everything doing the same thing
- Static
- Global state (including settings)
- Multiple responsibility paradigm
The single responsibility principle
YESThe single responsibility principle
YESThe story of EntityId
Step 2: EntityFactory
- Configuration state now at a more sensible place
- Still static, global state, violating SRP
The single responsibility principle
YESThe story of EntityId
Step 3: EntityId::newFromText()
- Again a less bad place to put the logic
- Still static
- Still pulling in global state
- Still violating SRP - value object + parsing service
The single responsibility principle
YESThe story of EntityId
Step 4: EntityIdParser
- State of the now
- No more static code
- Single responsibility!
The single responsibility principle
YESThe story of EntityId
What this cost
- Time spend on multiple changes
- Time spend on fixing bugs caused by the changes
- Time spend on re-learning
- General instability of our internal API
- Bad code introduced along the way we are now stuck with, ie EntityId->getPrefixedId()
The single responsibility principle
YESWrapping up
- SRP decreases complexity
- SRP decreases tight coupling
- SRP makes code easier to understand, use and test
- SRP increases flexibility
- SRP decreases time spend on making changes (ie ~80% of dev time)
- Think UNIX: each component does a single thing and does it well
- If your class description includes "and", you are probably violating SRP
- If it includes "all" or "everything", I will throw things at you
The single responsibility principle
YESThe single responsibility principle
YESFurther reading
- Single responsibility principle (Wikipedia)
- Single responsibility principle (Robert C. Martin writeup)
- SOLID (Wikipedia)
These slides