The document discusses several key principles of object-oriented design including:
- Managing dependencies between classes by following principles like single responsibility, dependency injection, and avoiding tight coupling.
- The importance of interfaces in segregating responsibilities and allowing for context independence and flexibility.
- Additional design concepts like the law of Demeter, messages over objects, and duck typing to create code that is change tolerant and easy to maintain over time.
9. Design is not an assembly line where similarly
trained workers construct identical widgets; it’s a
studio where like-minded artists sculpt custom applications.
Design is thus an art, the art of arranging code.
39. Single Responsibility, Open-Closed, Liskov
Substitution, Interface Segregation, and Dependency
Inversion.
DRY (Don’t Repeat Yourself)
Law of Demeter (LoD)
Principles
40. The so-called Gang of Four (Gof)
Skinny models - Service objects
Patterns
41. Design is more the art of preserving changeability than it
is the act of achieving perfection
45. Transparent The consequences of change should be obvious
in the code that is changing and in distant code that relies upon
it
Reasonable The cost of any change should be proportional to
the benefits the change achieves
Usable Existing code should be usable in new and unexpected
contexts
Exemplary The code itself should encourage those who
change it to perpetuate these qualities
50. Sandi Metz
“Sandi is the author of Practical Object-
Oriented Design in Ruby, and most recently
99 bottles. She has thirty years of experience
working on large object-oriented applications.
She’s spoken about programming, object-
oriented design and refactoring at numerous
conferences including Agile Alliance Technical
Conference, Craft Conf, Øredev, RailsConf,
and RubyConf. She believes in simple code
and straightforward explanations, and is the
proud recipient of a Ruby Hero award for her
contribution to the Ruby community. She
prefers working software, practical solutions
and lengthy bicycle trips (not necessarily in
that order). Find out more about Sandi at
sandimetz.com.
52. Design
What are design principles
What are design Patterns
When should I design?
How does one design ?
OO vs FP
Single Responsibility
What belongs to a class?
How do I organize my code?
Why does SR matter?
Code Introspection
How to write change tolerant codeData vs Behavior
When to design and when to replicate?
Dependencies
What is coupling? is it good or bad?
How to inject Dependencies
How to isolate dependencies
Seeing hidden dependencies
Which direction should we interact with them
Interfaces
Public vs Private
Responsibilities of interfaces
Intention
Context independence
Messages over objects
Developing trust
LoD
What is this? why is it important
What happens if I break the law?
How to avoid violations
Duck Typing
Understanding the quacks
Trusting ducks by choosing them wisely
Finding hidden ducks
Documentation
Sharing Code
Static vs Dynamic Typing
Inheritance
Where to use it?
Drawing up relationships
What happens when you misapply inheritance
Creating abstract classes
Template Method Pattern
Superclasses and Subclasses
Editor's Notes
Lets look at design
Our internal calculators are always running, comparing total amount accomplished to overall effort expended. When the cost of doing work exceeds its value, our efforts feel wasted.
Keep that in mind.. it’s about perspective. 30years of experience within the industry boiled to this one realization.
This is some art I saw in 2006 at the Standard bank exhibition of Pablo Picasso and his works, He went out to show the different styles of art that something that looks simple can be complex within it’s own right.
Art is a funny thing, because it’s also all about perspective
Close your eyes: Imagine writing a new application. Imagine that this application comes equipped with a complete and correct set of requirements. And if you will, imagine one more thing: once written, this application need never change.
How would such a challenge make you feel, at first you may be excited. Would you want to write the fastest code ever? would it need to look nice or make sense? What sort of constraints do we eliminate because we know the app will never change? So what are these “constraints” really?
It always dose.What sort of constraints are necessary for change? But really the question is can something that seems to be holding us back be really whats holding us up.
Knowing this, what do we do?
we need to know our enemy!
Object-oriented applications are made up of parts that interact to produce the behavior of the whole. The parts are objects; interactions are embodied in the messages that pass between them. Getting the right message to the correct target object requires that the sender of the message know things about the receiver. This knowledge creates dependencies between the two and these dependencies stand in the way of change.
This code looks simple enough to follow, but we have created many dependancies. • The name of another class. Gear expects a class named Wheel to exist.
• The name of a message that it intends to send to someone other than self. Gear expects a Wheel instance to respond to diameter.
• The arguments that a message requires. Gear knows that Wheel.new requires a rim and a tire.
• The order of those arguments. Gear knows the first argument to Wheel.new should be rim, the second, tire.
1. The name of another class. Gear expects a class named Wheel to exist.
2. The name of a message that it intends to send to someone other than self. Gear expects a Wheel instance to respond to diameter.
3. The arguments that a message requires. Gear knows that Wheel.new requires a rim and a tire.
4. The order of those arguments. Gear knows the first argument to Wheel.new should be rim, the second, tire.
Anyone can arrange code to make it work right now. Today’s application can be beat into submission by sheer force of will. It’s a standing target at a known range. It is at your mercy.
Creating an easy-to-change application, however, is a different matter. Your application needs to work right now just once; it must be easy to change forever. This quality of easy changeability reveals the craft of programming. Achieving it takes knowledge, skill, and a bit of artistic creativity.
These dependencies couple Gear to Wheel. Alternatively, you could say that each coupling creates a dependency. The more Gear knows about Wheel, the more tightly coupled they are. The more tightly coupled two objects are, the more they behave like a single entity. If you make a change to Wheel you may find it necessary to make a change to Gear. If you want to reuse Gear, Wheel comes along for the ride. When you test Gear, you’ll be testing Wheel too.
We have now taken the dependency and injected it into the object via the params. This is good because now Gear can take any object that has a `gear_inches` method and it will work. Free duck typing!
Sometimes doing a direct dependency injection can be tough because of how coupled the code has become. In these instances doing something like this, is second best. It exposes the dependancies right within the initialize block
The intent is to explicitly expose the dependency while reducing its reach into your class.
Managing the order dependency is one that is rarely thought of. But as systems become more complex using this design becomes more important.
Not only will it be the guide post of your design of the code to come it will make testing a dream because you will isolate the problems much faster.
If making a change to your model breaks all the spec’s within the model or even other spec’s outside of the scope of what you are working on, this will indicate that your models are too closely coupled and that your tests have now become a dependency themselves.
In a class-based OO language like Ruby, methods are defined in classes.
The classes you create will affect how you think about your application forever.
They define a virtual world, one that constrains the imagination of everyone downstream. You are constructing a box that may be difficult to think outside of.
If your application succeeds many of the decisions you make today will need to be changed later.
When that day comes, your ability to successfully make those changes will be determined by your application’s design.
Going with my mindful theme last year, these principles are now my new guide posts in making decisions when writing any code.Now with this in mind Sandi Metz takes years of experience and shows us how to apply these principles into almost every facet of our current work environment (Since we work with OO languages).So Is this book worth it? Yes, yes and yes again.
Each subtopic here could be a full blown talk at a conference.
But the book has two main theme’s: