1 Chapter 7 Graphical User Interface (GUI) and Object-Oriented Design (OOD)
OOD - Object orientated design
-
Upload
ruberto-paulo -
Category
Technology
-
view
30 -
download
1
Transcript of OOD - Object orientated design
OOD
We want to do our best work.
We want our work to have meaning
We want to have fun along the way
Two major themes being Designand Messages over objects
Design
Failures of OOD might look like failures of coding technique but they are actually failures
of perspective.
Source: Pablo Picasso - Buffalo Art
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.
How does Design affect us?
Perspective.
Unfortunately, something will change.
The customers didn’t know what they wanted.
They didn’t say what they meant.
You didn’t understand their needs.
You’ve learned how to do something better.
Even applications that are perfect in every way are not stable.
The application was a huge success, now everyone wants more.
Change is unavoidable. It is ubiquitous, omnipresent, and inevitable.
Source: http://more-sky.com/
Dependency
Object-oriented design is about managing dependencies.
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
Your goal is to model your application, using classes, such that it does what it is supposed to do right now and is also easy to change later.
1 class Gear 2 attr_reader :chainring, :cog, :rim, :tire 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @rim = rim 7 @tire = tire 8 end 9 10 def gear_inches 11 ratio * Wheel.new(rim, tire).diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
Dependency injection
1 class Gear 2 attr_reader :chainring, :cog, :wheel 3 def initialize(chainring, cog, wheel) 4 @chainring = chainring 5 @cog = cog 6 @wheel = wheel 8 end 9 10 def gear_inches 11 ratio * wheel.diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, Wheel.new(26, 1.5)).gear_inches
Dependency aversion
1 class Gear 2 attr_reader :chainring, :cog, :wheel 3 def initialize(chainring, cog, rim, tire) 4 @chainring = chainring 5 @cog = cog 6 @wheel = Wheel.new(rim, tire) 8 end 9 10 def gear_inches 11 ratio * wheel.diameter 12 end 13 # ... 14 end 15 16 Gear.new(52, 11, 26, 1.5).gear_inches
Order Dependency
1 class Gear 2 attr_reader :chainring, :cog, :tire 3 def initialize(args) 4 @chainring = args[:chainring] 5 @cog = args[:cog] 6 @wheel = args[:wheel] 7 end 8 9 def gear_inches 10 ratio * wheel.diameter 11 end 12 # ... 13 end 14 15 Gear.new( 16 :cog => 11, 17 :chainring => 52, 18 :wheel => Wheel.new(26, 1.5)).gear_inches
Is your code too coupled to your tests?
Tools for design
Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion. DRY (Don’t Repeat Yourself) Law of Demeter (LoD)
Principles
The so-called Gang of Four (Gof) Skinny models - Service objects
Patterns
Design is more the art of preserving changeability than it is the act of achieving perfection
Virtual World
You will never know less than you know right now.
Keep your code TRUE
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 contextsExemplary The code itself should encourage those who change it to perpetuate these qualities
Challenge - https://gitlab.com/LegendaryRob/WizSys
Example
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.
Why this book?
Design
What are design principlesWhat 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 IntrospectionHow 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 DependenciesHow to isolate dependencies
Seeing hidden dependencies
Which direction should we interact with them
Interfaces Public vs Private
Responsibilities of interfacesIntention
Context independenceMessages over objects
Developing trust
LoDWhat is this? why is it important
What happens if I break the law?How to avoid violations
Duck TypingUnderstanding the quacks
Trusting ducks by choosing them wiselyFinding hidden ducks
DocumentationSharing Code
Static vs Dynamic Typing
InheritanceWhere to use it?
Drawing up relationshipsWhat happens when you misapply inheritance
Creating abstract classesTemplate Method Pattern
Superclasses and Subclasses