3. SOLID
Five basic principles of object-oriented programming and
design that deals with “dependency management”
● S SRP Single responsibility principle
● O OCP Open/closed principle
● L LSP Liskov substitution principle
● I ISP Interface segregation principle
● D DIP Dependency inversion principle
4. Principles vs. Patterns
A pattern in “is a general reusable solution to a
commonly occurring problem within a given context in
software design”
● Use a pattern to solve a known problem.
● Use the principles to identify the problem and come up
with the solution.
5. Single Responsibility Principle
“A class should have one and only one reason to change,
meaning that a class should have only one job.”
Not responsible for bug fixes or refactoring. Those things
are the responsibility of the programmer, not of the
program
Then what’s a program responsible to?
6. First Example
class Employee {
public Money calculatePay()
public void save()
public String reportHours()
}
Three reasons to change:
● The business rules having to do with calculating pay.
● The database schema.
● The format of the hours report.
7. Step by Step Example
New request has arrived:
1. Generate a weekly report of online users
2. Send it to Jill in France
9. 1- Monthly instead of weekly
3- Jill gets fired
2- Change
report’s format
to CSV
Possible Reasons to Change
10. 1- Get a list of users upon a criteria
2- Format the message
3- Deliver the report
Break down:
Responsibilities
handled in each
method in one
class
4- Put it all togather
14. Sketch - Relations
ReportMailer UserWeeklyReport
ReportDataCSVCompiler UserWeeklyReportData
User
Formatting
Parsing users
Getting users
Mail
delivery
Report generation
15. Separation of Concerns
Classes are not the end. Applicable on every level!
It goes back even to the days when Structured
Programming was all the hype
Applicable on functions, classes, modules, …
16. Separation of Concerns
● OOP languages separate concerns into objects
● Architectural design patterns like MVC separate
content from presentation and the data-processing
(model) from content
● Service-oriented design use services
● Procedural languages such as C use functions.
17. Method-wise Example
● In a class that handles syncing local data with Dropbox
● Show up an alert view to handle some clashes
● Due to some design limitation, the following method
gets called to handle the user’s choice for each alert
-alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex
19. Response to “Notepad clashes”
alert
Three
sub
cases!
Response to “older DB”
alert
Handle project clashes
20. Logical separation
The purpose of this method is clear:
“switching”
Each of the other three methods handle
one case
1
2
3
We can apply the same
here
1
2
3
21. Examples of “Frequent” Responsibilities
● Persistence to storage
● Validation
● Notification
● Error Handling
● Logging
● Class Selection / Instantiation
● Formatting
● Parsing
● Mapping
22. How do you know that SRP is violated?
First answer: “Length”
Popular choices:
Classes shouldn’t exceed 200 lines of code (exclude
comments)
Methods shouldn’t exceed 30 lines of code
Is this a solid metric? … Not exactly!
24. Less than 200
lines of code
Does it follow SRP
correctly?
Code to “prepare”
for requests
performed for
Dashboard
Descriptors.
Similar to routing
Mapping
JSON <-> Objects
Various requests
performed on
Dashboard
25. Reasons “Mapping” part would change
● Web request refactored
● Dashboard needed to be used in
another request with different
parameters
26. Encapsulate a single request into a proxy object
Few reasons to make this class change
Biggest benefit: Dashboard is simpler and shorter
27. Length ??
So length isn’t a very accurate metric.
If a class is higher than 200 loc, then it’s problem!
If it’s fewer than 200 loc, that doesn’t mean you’re clear!
28. SRP Violation Smells
● Class has too many instance variables and methods
○ Especially, when you always use a group of them together
● The test class becomes too complicated
○ Too many mock objects
○ Too many test cases
● Use “and” or “or” in names
● Class with low cohesion
○ Many parts not related to each other
● Class / Method is Long
29. SRP Violation Smells
● Change In One Place Breaks Another
● Shotgun Effect
● Unable to Encapsulate a Module
● Class has too many dependencies
30. Why?
● Organize the code
○ So you know where to look for the next request
● Code Changes
○ If you have to refactor one class, only one class will change
● Less fragile
○ “You were only supposed to send an email, how did you end
up deleting all the data?”
31. Why?
● Testability
○ Less test cases for a class with one job to do
● Code sharing
○ All previous reasons are equally or more important than this
one!
○ Don’t wait till you have to reuse the code, start breaking
down your code when it makes sense.
32. Complex view example
A controller that populates a table view and a charts
area with data retrieved from another object
36. Data source to
ChartsEngine: Provides
needed content to the
object that draws the
charts
~ 50 lines
Source to the
side table view
~ 40 lines
Another responsibility: Provide a
widget builder so other object can
use it build it.
Get data and show it in
view
39. Add a couple of
lines to initialize
those helpers
and provide
data to them
And the view controller
drops to ~ 100 lines of
total code
One clear responsibility:
Get data from a data
loader object and
provide to “view source”
object
We didn’t handle
that yet! But you get
the picture...
40. Correlation with Frameworks
Sometimes, the way the framework is designed makes it
easy to put all your code in one place
● iOS: View controllers and application delegates
● Android: Activities
● RoR: ActiveRecord models
41. Monster AppDelegate - Example Responsibilities
● Receive application’s notifications
● Register for a 3rd party service
● Handle global view settings
● Show notification for version updates and handle
user’s action
● Dropbox connection
● Handle push notifications
42. Example Patterns to Decompose Fat Classes
● Standard composition / Delegation
○ Two basic design patterns
○ Break a complex class into smaller ones
● View objects / View model / Presenter
○ If some logic is needed to prepare the model for view
● Decorator
○ Put the extra behaviour in a new class
● Specific patterns to specific problems
○ e.g. Factory / Builder for object creation
43. References
1. The Principles of OOD (Uncle Bob)
2. SOLID (Wikipedia)
3. Software Design Pattern (Wikipedia)
4. Uncle Bob (blog.8thlight.com)
5. Ruby Example (John Bohn)
6. Separation of Concerns (Wikipedia)
7. Examples of Responsiblities (deviq.com)
8. Why SRP and SRP Smells (Java Code Geeks)
9. Fat ActiveRecord Models (blog.codeclimate.com)
10. Active Record Breaks SRP by Design (sitepoint.com)
11. Active Record Breaks SRP by Design (programmers.stackexchange)
12. Patterns to Destroy Big View Controllers (Soroush Khanlou)