SlideShare una empresa de Scribd logo
1 de 57
Design patterns in Ruby Aleksander Dąbrowski 3 Mar 2009 www.wrug.eu
What are design patterns? Why should I know them?
For Money ;) They sound like something advance and  professional
Popular problems are already solved Don't invent the wheel
 
Design pattern is description of popular solution
Common language
Plan: 1. Observer 2. Template Method 3. Strategy
Let's go to the point
1. Observer We want to be notified when something change status
Example: Cat is observing a mouse hole. When mouse leaves the hole, cat starts to hunt.
class Hole def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' end end
How to make the cat observer?
module Observable def initialize @observers=[] end def add_observer(observer) @observers << observer end def delete_observer(observer) @observers.delete(observer) end def notify_observers @observers.each do |observer| observer.update(self) end end end
class Cat def update hunt_the_mouse end private: def hunt_the_mouse jump kill ... end end
class Hole include Observable def observe( cat ) add_observer( cat ) end def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' notify_observers end end
 
How to make the cat observer? In Ruby simply use Observable mixin require 'observer'
require 'observer' class Hole include Observable def observe( cat ) add_observer( cat ) end def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' changed notify_observers( self ) end end
Observable: add_observer( observer ) changed( state = true ) changed?  count_observers  delete_observer( observer )  delete_observers  notify_observers( *arg )
Are you already using observer?
class EmployeeObserver < ActiveRecord::Observer def after_create(employee) # New employee record created. end def after_update(employee) # Employee record updated end def after_destroy(employee) # Employee record deleted. end end
2. Template Method
Use it when: part of code has to cope with different tasks  probably more changes will be made
Generating HTML report
class Report def initialize @title = 'Monthly Report' @text =  ['Things are going', 'really, really well.'] end def output_report puts('<html>') puts('  <head>') puts(&quot;  <title>#{@title}</title>&quot;) puts('  </head>') puts('  <body>') @text.each do |line| puts(&quot;  <p>#{line}</p>&quot; ) end puts('  </body>') puts('</html>') end end
report = Report.new report.output_report Output <html> <head> <title>Monthly Report</title> </head> <body> <p>Things are going</p> <p>really, really well.</p> </body> </html>
How to add generating plain text report?
def output_report(format) if format == :plain puts(&quot;*** #{@title} ***&quot;) elsif format == :html puts('<html>') puts('  <head>') puts(&quot;  <title>#{@title}</title>&quot;) puts('  </head>') puts('  <body>') else raise &quot;Unknown format: #{format}&quot; end @text.each do |line| if format == :plain puts(line) else puts(&quot;  <p>#{line}</p>&quot; ) end end
It's little complicated. What will happen when we add PDF?
Isolation of elements
class Report def initialize @title = 'Monthly Report' @text =  ['Things are going', 'really, really well.'] end def output_report output_start output_head output_body_start output_body output_body_end output_end end def output_body @text.each do |line| output_line(line) end end
Use abstract classes
Ruby doesn't has abstract classes
Solution: Use 'raise'
def output_body @text.each do |line| output_line(line) end end def output_start raise 'Called abstract method: output_start' end def output_head raise 'Called abstract method: output_head' end def output_body_start raise 'Called abstract method: output_body_start' end
Two subclasses: html & plain  ( pdf, rdf, doc... in future)
class HTMLReport < Report def output_start puts('<html>') end def output_head puts('  <head>') puts(&quot;  <title>#{@title}</title>&quot;) puts('  </head>') end def output_body_start puts('<body>') end def output_line(line) puts(&quot;  <p>#{line}</p>&quot;) end
class PlainTextReport < Report def output_start end def output_head puts(&quot;**** #{@title} ****&quot;) puts end def output_body_start end def output_line(line) puts line end
How to use it?
report = HTMLReport.new report.output_report report = PlainTextReport.new report.output_report
Subclasses covers abstract methods They do not cover output report
Hook methods Non abstract methods, which can be covered.
class Report (...) def output_start end def output_head output_line( @title ) end def output_body_start end def output_line( line ) raise 'Called abstract method: output_line' end
report = HTMLReport.new
Duck Typing “ If it looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.” Ronald Reagen
Ruby has it Duck Typing
3. Strategy
class Formatter def output_report(title, text) raise 'Abstract method called' end end class HTMLFormatter < Formatter def output_report( title, text ) puts('<html>') puts('  <head>') puts(&quot;  <title>#{title}</title>&quot;) puts('  </head>') puts('  <body>') text.each do |line| puts(&quot;  <p>#{line}</p>&quot; ) end puts('  </body>') puts('</html>') end end
class PlainTextFormatter < Formatter def output_report(title, text) puts(&quot;***** #{title} *****&quot;) text.each do |line| puts(line) end end end
class Report attr_reader :title, :text attr_accessor :formatter def initialize(formatter) @title = 'Monthly Report' @text =  ['Things are going', 'really, really well.'] @formatter = formatter end def output_report @formatter.output_report( @title, @text) end end
We can change strategy during program execution
report = Report.new(HTMLFormatter.new) report.output_report report.formatter = PlainTextFormatter.new report.output_report
Sources
Bible
Ruby only
Simple in Java

Más contenido relacionado

La actualidad más candente

La actualidad más candente (18)

Create a web-app with Cgi Appplication
Create a web-app with Cgi AppplicationCreate a web-app with Cgi Appplication
Create a web-app with Cgi Appplication
 
Design attern in php
Design attern in phpDesign attern in php
Design attern in php
 
Introduction to web programming with JavaScript
Introduction to web programming with JavaScriptIntroduction to web programming with JavaScript
Introduction to web programming with JavaScript
 
Javascript Primer
Javascript PrimerJavascript Primer
Javascript Primer
 
Clean Code Principles
Clean Code PrinciplesClean Code Principles
Clean Code Principles
 
CGI With Object Oriented Perl
CGI With Object Oriented PerlCGI With Object Oriented Perl
CGI With Object Oriented Perl
 
SQL -PHP Tutorial
SQL -PHP TutorialSQL -PHP Tutorial
SQL -PHP Tutorial
 
TDD with PhpSpec
TDD with PhpSpecTDD with PhpSpec
TDD with PhpSpec
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
PHP MATERIAL
PHP MATERIALPHP MATERIAL
PHP MATERIAL
 
Perl Modules
Perl ModulesPerl Modules
Perl Modules
 
An Introduction To Perl Critic
An Introduction To Perl CriticAn Introduction To Perl Critic
An Introduction To Perl Critic
 
C# conventions & good practices
C# conventions & good practicesC# conventions & good practices
C# conventions & good practices
 
YAPC::NA 2007 - An Introduction To Perl Critic
YAPC::NA 2007 - An Introduction To Perl CriticYAPC::NA 2007 - An Introduction To Perl Critic
YAPC::NA 2007 - An Introduction To Perl Critic
 
name name2 n2
name name2 n2name name2 n2
name name2 n2
 
ppt9
ppt9ppt9
ppt9
 
name name2 n2.ppt
name name2 n2.pptname name2 n2.ppt
name name2 n2.ppt
 
ppt18
ppt18ppt18
ppt18
 

Destacado

The High School Connection: Bridging the Gap Between High School and College
The High School Connection: Bridging the Gap Between High School and CollegeThe High School Connection: Bridging the Gap Between High School and College
The High School Connection: Bridging the Gap Between High School and College
Elizabeth Nesius
 
Lecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administrationLecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administration
Mohammed Farrag
 
Europa Del Settecento
Europa Del SettecentoEuropa Del Settecento
Europa Del Settecento
mapaa
 
Power Point Polmoni
Power Point PolmoniPower Point Polmoni
Power Point Polmoni
mapaa
 

Destacado (20)

Jak vytvořit pozoruhodnou web aplikaci
Jak vytvořit pozoruhodnou web aplikaciJak vytvořit pozoruhodnou web aplikaci
Jak vytvořit pozoruhodnou web aplikaci
 
Retrospective 2008 The Surfer’s Year
Retrospective 2008 The Surfer’s YearRetrospective 2008 The Surfer’s Year
Retrospective 2008 The Surfer’s Year
 
Pigmalió i Prometeu
Pigmalió i PrometeuPigmalió i Prometeu
Pigmalió i Prometeu
 
The High School Connection: Bridging the Gap Between High School and College
The High School Connection: Bridging the Gap Between High School and CollegeThe High School Connection: Bridging the Gap Between High School and College
The High School Connection: Bridging the Gap Between High School and College
 
Oracle Exec Summary 7000 Unified Storage
Oracle Exec Summary 7000 Unified StorageOracle Exec Summary 7000 Unified Storage
Oracle Exec Summary 7000 Unified Storage
 
BizTalk Custom Adapters Toronto Code Camp Presentation
BizTalk Custom Adapters  Toronto Code Camp PresentationBizTalk Custom Adapters  Toronto Code Camp Presentation
BizTalk Custom Adapters Toronto Code Camp Presentation
 
Debt Taxes
Debt TaxesDebt Taxes
Debt Taxes
 
E learning Simplified for 8th Graders
E learning Simplified for 8th GradersE learning Simplified for 8th Graders
E learning Simplified for 8th Graders
 
Mobile Web Rock
Mobile Web RockMobile Web Rock
Mobile Web Rock
 
Future Success Web 2 Overview
Future Success Web 2 OverviewFuture Success Web 2 Overview
Future Success Web 2 Overview
 
Tally Sheet Results - Technology Habits
Tally Sheet Results - Technology HabitsTally Sheet Results - Technology Habits
Tally Sheet Results - Technology Habits
 
Axiologix Company Presentation Jan 2011
Axiologix Company Presentation Jan 2011Axiologix Company Presentation Jan 2011
Axiologix Company Presentation Jan 2011
 
Lecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administrationLecture 3 Perl & FreeBSD administration
Lecture 3 Perl & FreeBSD administration
 
Web并发模型粗浅探讨
Web并发模型粗浅探讨Web并发模型粗浅探讨
Web并发模型粗浅探讨
 
精益创业讨论
精益创业讨论精益创业讨论
精益创业讨论
 
5 things MySql
5 things MySql5 things MySql
5 things MySql
 
Europa Del Settecento
Europa Del SettecentoEuropa Del Settecento
Europa Del Settecento
 
Aptso cosechas 2010
Aptso cosechas 2010Aptso cosechas 2010
Aptso cosechas 2010
 
Ruby In Enterprise Development
Ruby In Enterprise DevelopmentRuby In Enterprise Development
Ruby In Enterprise Development
 
Power Point Polmoni
Power Point PolmoniPower Point Polmoni
Power Point Polmoni
 

Similar a Design Patterns in Ruby

Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
Magecom Ukraine
 
Washington Practitioners Significant Changes To Rpc 1.5
Washington Practitioners Significant Changes To Rpc 1.5Washington Practitioners Significant Changes To Rpc 1.5
Washington Practitioners Significant Changes To Rpc 1.5
Oregon Law Practice Management
 
Paulo Freire Pedagpogia 1
Paulo Freire Pedagpogia 1Paulo Freire Pedagpogia 1
Paulo Freire Pedagpogia 1
Alejandra Perez
 
Jerry Shea Resume And Addendum 5 2 09
Jerry  Shea Resume And Addendum 5 2 09Jerry  Shea Resume And Addendum 5 2 09
Jerry Shea Resume And Addendum 5 2 09
gshea11
 
Open Source Package Php Mysql 1228203701094763 9
Open Source Package Php Mysql 1228203701094763 9Open Source Package Php Mysql 1228203701094763 9
Open Source Package Php Mysql 1228203701094763 9
isadorta
 

Similar a Design Patterns in Ruby (20)

Python scripting kick off
Python scripting kick offPython scripting kick off
Python scripting kick off
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
 
Smarter Interfaces with jQuery (and Drupal)
Smarter Interfaces with jQuery (and Drupal)Smarter Interfaces with jQuery (and Drupal)
Smarter Interfaces with jQuery (and Drupal)
 
Python - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave ParkPython - Getting to the Essence - Points.com - Dave Park
Python - Getting to the Essence - Points.com - Dave Park
 
Introduction To Lamp
Introduction To LampIntroduction To Lamp
Introduction To Lamp
 
How Xslate Works
How Xslate WorksHow Xslate Works
How Xslate Works
 
Python 3000
Python 3000Python 3000
Python 3000
 
Система рендеринга в Magento
Система рендеринга в MagentoСистема рендеринга в Magento
Система рендеринга в Magento
 
WordPress Development Confoo 2010
WordPress Development Confoo 2010WordPress Development Confoo 2010
WordPress Development Confoo 2010
 
MMBJ Shanzhai Culture
MMBJ Shanzhai CultureMMBJ Shanzhai Culture
MMBJ Shanzhai Culture
 
Washington Practitioners Significant Changes To Rpc 1.5
Washington Practitioners Significant Changes To Rpc 1.5Washington Practitioners Significant Changes To Rpc 1.5
Washington Practitioners Significant Changes To Rpc 1.5
 
Paulo Freire Pedagpogia 1
Paulo Freire Pedagpogia 1Paulo Freire Pedagpogia 1
Paulo Freire Pedagpogia 1
 
Jerry Shea Resume And Addendum 5 2 09
Jerry  Shea Resume And Addendum 5 2 09Jerry  Shea Resume And Addendum 5 2 09
Jerry Shea Resume And Addendum 5 2 09
 
Majlis Persaraan Pn.Hjh.Normah bersama guru-guru Sesi Petang
Majlis Persaraan Pn.Hjh.Normah bersama guru-guru Sesi PetangMajlis Persaraan Pn.Hjh.Normah bersama guru-guru Sesi Petang
Majlis Persaraan Pn.Hjh.Normah bersama guru-guru Sesi Petang
 
Agapornis Mansos - www.criadourosudica.blogspot.com
Agapornis Mansos - www.criadourosudica.blogspot.comAgapornis Mansos - www.criadourosudica.blogspot.com
Agapornis Mansos - www.criadourosudica.blogspot.com
 
LoteríA Correcta
LoteríA CorrectaLoteríA Correcta
LoteríA Correcta
 
PHP MySQL
PHP MySQLPHP MySQL
PHP MySQL
 
Ruby For Java Programmers
Ruby For Java ProgrammersRuby For Java Programmers
Ruby For Java Programmers
 
Open Source Package PHP & MySQL
Open Source Package PHP & MySQLOpen Source Package PHP & MySQL
Open Source Package PHP & MySQL
 
Open Source Package Php Mysql 1228203701094763 9
Open Source Package Php Mysql 1228203701094763 9Open Source Package Php Mysql 1228203701094763 9
Open Source Package Php Mysql 1228203701094763 9
 

Último

+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 

Último (20)

Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 

Design Patterns in Ruby

  • 1. Design patterns in Ruby Aleksander Dąbrowski 3 Mar 2009 www.wrug.eu
  • 2. What are design patterns? Why should I know them?
  • 3. For Money ;) They sound like something advance and professional
  • 4. Popular problems are already solved Don't invent the wheel
  • 5.  
  • 6. Design pattern is description of popular solution
  • 8. Plan: 1. Observer 2. Template Method 3. Strategy
  • 9. Let's go to the point
  • 10. 1. Observer We want to be notified when something change status
  • 11. Example: Cat is observing a mouse hole. When mouse leaves the hole, cat starts to hunt.
  • 12. class Hole def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' end end
  • 13. How to make the cat observer?
  • 14. module Observable def initialize @observers=[] end def add_observer(observer) @observers << observer end def delete_observer(observer) @observers.delete(observer) end def notify_observers @observers.each do |observer| observer.update(self) end end end
  • 15. class Cat def update hunt_the_mouse end private: def hunt_the_mouse jump kill ... end end
  • 16. class Hole include Observable def observe( cat ) add_observer( cat ) end def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' notify_observers end end
  • 17.  
  • 18. How to make the cat observer? In Ruby simply use Observable mixin require 'observer'
  • 19. require 'observer' class Hole include Observable def observe( cat ) add_observer( cat ) end def enter( mouse ) puts '#{ mouse.name } is safe' end def exit( mouse ) puts '#{ mouse.name } is not safe' changed notify_observers( self ) end end
  • 20. Observable: add_observer( observer ) changed( state = true ) changed? count_observers delete_observer( observer ) delete_observers notify_observers( *arg )
  • 21. Are you already using observer?
  • 22. class EmployeeObserver < ActiveRecord::Observer def after_create(employee) # New employee record created. end def after_update(employee) # Employee record updated end def after_destroy(employee) # Employee record deleted. end end
  • 24. Use it when: part of code has to cope with different tasks probably more changes will be made
  • 26. class Report def initialize @title = 'Monthly Report' @text = ['Things are going', 'really, really well.'] end def output_report puts('<html>') puts(' <head>') puts(&quot; <title>#{@title}</title>&quot;) puts(' </head>') puts(' <body>') @text.each do |line| puts(&quot; <p>#{line}</p>&quot; ) end puts(' </body>') puts('</html>') end end
  • 27. report = Report.new report.output_report Output <html> <head> <title>Monthly Report</title> </head> <body> <p>Things are going</p> <p>really, really well.</p> </body> </html>
  • 28. How to add generating plain text report?
  • 29. def output_report(format) if format == :plain puts(&quot;*** #{@title} ***&quot;) elsif format == :html puts('<html>') puts(' <head>') puts(&quot; <title>#{@title}</title>&quot;) puts(' </head>') puts(' <body>') else raise &quot;Unknown format: #{format}&quot; end @text.each do |line| if format == :plain puts(line) else puts(&quot; <p>#{line}</p>&quot; ) end end
  • 30. It's little complicated. What will happen when we add PDF?
  • 32. class Report def initialize @title = 'Monthly Report' @text = ['Things are going', 'really, really well.'] end def output_report output_start output_head output_body_start output_body output_body_end output_end end def output_body @text.each do |line| output_line(line) end end
  • 34. Ruby doesn't has abstract classes
  • 36. def output_body @text.each do |line| output_line(line) end end def output_start raise 'Called abstract method: output_start' end def output_head raise 'Called abstract method: output_head' end def output_body_start raise 'Called abstract method: output_body_start' end
  • 37. Two subclasses: html & plain ( pdf, rdf, doc... in future)
  • 38. class HTMLReport < Report def output_start puts('<html>') end def output_head puts(' <head>') puts(&quot; <title>#{@title}</title>&quot;) puts(' </head>') end def output_body_start puts('<body>') end def output_line(line) puts(&quot; <p>#{line}</p>&quot;) end
  • 39. class PlainTextReport < Report def output_start end def output_head puts(&quot;**** #{@title} ****&quot;) puts end def output_body_start end def output_line(line) puts line end
  • 40. How to use it?
  • 41. report = HTMLReport.new report.output_report report = PlainTextReport.new report.output_report
  • 42. Subclasses covers abstract methods They do not cover output report
  • 43. Hook methods Non abstract methods, which can be covered.
  • 44. class Report (...) def output_start end def output_head output_line( @title ) end def output_body_start end def output_line( line ) raise 'Called abstract method: output_line' end
  • 46. Duck Typing “ If it looks like a duck, swims like a duck and quacks like a duck, then it probably is a duck.” Ronald Reagen
  • 47. Ruby has it Duck Typing
  • 49. class Formatter def output_report(title, text) raise 'Abstract method called' end end class HTMLFormatter < Formatter def output_report( title, text ) puts('<html>') puts(' <head>') puts(&quot; <title>#{title}</title>&quot;) puts(' </head>') puts(' <body>') text.each do |line| puts(&quot; <p>#{line}</p>&quot; ) end puts(' </body>') puts('</html>') end end
  • 50. class PlainTextFormatter < Formatter def output_report(title, text) puts(&quot;***** #{title} *****&quot;) text.each do |line| puts(line) end end end
  • 51. class Report attr_reader :title, :text attr_accessor :formatter def initialize(formatter) @title = 'Monthly Report' @text = ['Things are going', 'really, really well.'] @formatter = formatter end def output_report @formatter.output_report( @title, @text) end end
  • 52. We can change strategy during program execution
  • 53. report = Report.new(HTMLFormatter.new) report.output_report report.formatter = PlainTextFormatter.new report.output_report
  • 55. Bible