Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Forget about classes, welcome objects

kurko
July 28, 2013

Forget about classes, welcome objects

This is a talk about how to fight complexity using OO forgotten concepts.

kurko

July 28, 2013
Tweet

More Decks by kurko

Other Decks in Programming

Transcript

  1. Alexandre de Oliveira (@kurko) Forget about classes, welcome objects

  2. None
  3. None
  4. Perspective

  5. Alan Kay

  6. “Point of view is worth 80 IQ points” - Alan

    Kay
  7. None
  8. VI

  9. 6

  10. Reality as we conceive it

  11. Source: http://2.bp.blogspot.com/_EussjcZFO-c/SW1ITAQSlRI/AAAAAAAAAZY/Zmn7X88qBHk/s400/Princess+Anne+says+hello.jpg

  12. OOP?

  13. “OOP to me means only messaging, local retention and protection

    and hiding of state” Alan Kay
  14. None
  15. None
  16. None
  17. Complexity http://dougbelshaw.com/presentations/2012/ILTA/assets/complexity.jpg

  18. Problem #1: disorganisation

  19. ONE BIG OBJECT™

  20. many small objects collaborating with each other

  21. http://20px.com/wp-content/uploads/2013/02/unicorn_pooping_a_rainbow_20px.jpg

  22. such complexity, much wow

  23. http://adeviantman.deviantart.com/art/Pink-Fluffy-Unicorns-Dancing-On-Rainbows-315632047

  24. Problem #2: procedural code

  25. Domain Organization Project Stories Members Importing projects from Pivotal Tracker

  26. class ImportationService ! ! ! ! ! ! ! !

    ! ! end
  27. class ImportationService def process orgs = Organizations.new(client).import end end

  28. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end ! ! ! end end
  29. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end projects.each do |project| Members.new(client).import end end end
  30. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end projects.each do |project| Members.new(client).import Stories.new(client).import end end end
  31. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end projects.each do |project| Members.new(client).import Stories.new(client).import unless client.github? end end end
  32. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end projects.each do |project| Members.new(client).import Stories.new(client).import unless client.github? end end end Beginning of the end
  33. def process_extension!(extension_price, options={}) options.reverse_merge!({ :credit_card => user.default_credit_card, :billing_address => options[:credit_card].try(:billing_address)

    || user.default_address, :store => order.store, :tax => tax, :days => 14, :buyout => false }) ! creator = options[:creator] return process_extension_without_charge!(options) if options[:no_charge] ! response = Payment::Gateway.charge!( extension_price.cents.to_f/100, options[:credit_card].ext_cc_id, self.user.id, options[:store].try(:address).try(:country) ) ! # payment failed unless response[:ext_transaction_id].present? self.order.order_responses.create(:message => response[:error]) self.errors.add(:base, response[:error]) return false end ! data = { :ext_transaction_id => response[:ext_transaction_id], :parent_order_id => self.order.id, :parent_order_item_id => self.id, :ccauth_reply_authorization_code => response[:ccauth_reply_authorization_code] } ! if options[:buyout] # it's a buyout OrderTransaction.buyout!( self.order.currency, extension_price.cents - options[:tax].cents, self, data, creator ) ! OrderTransaction.tax_charged!( self.order.currency, options[:tax].cents, self, data, creator ) ! process_convert_to_purchase! ! else # it's a regular extension begin OrderTransaction.extension!( "#{options[:days]} days", self.order.currency, extension_price.cents - options[:tax].cents, self, data, creator ) OrderTransaction.tax_charged!( self.order.currency, options[:tax].cents, self, data, creator ) # Increment extension days for current Item self.increment(:extension_days, options[:days]) self.update_attribute(:state, 'shipped_with_customer_extended') OrderItemMailer.rental_extended(self).deliver rescue Net::SMTPSyntaxError => exception Airbrake.notify( :error_class => exception.class.to_s, :error_message => "Bad Email Address Format. Order Item: #{self.id}. Email: #{self.order.user.email}", :parameters => self.attributes, :backtrace => caller) end end ! return true end 100+ LoC Real Code™
  34. Flattened Domain Organization Project Stories Members

  35. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg Curiosity

  36. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg 2.5 M LoC

  37. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg Written in C

  38. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg Completely OOP

  39. WAT http://www.gazetadopovo.com.br/blogs/cinema-em-casa/wp-content/uploads/sites/30/2013/05/short2circuit2654.jpg

  40. http://www.wired.com/wp-content/uploads/blogs/design/wp-content/uploads/2012/08/MSL-Rover-NX-CAD-model.jpg

  41. Path Finder Radio receiver Sample Analysis Descent Imager ChemCam UV

    Sensor Engine Wheels
  42. Component 1 Component 2 Component 3 Component n Message Queue

    Component 4 Component 5 Component 6 Component z
  43. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg • Lots of messages • No mutexes, no transactional

    memory • Complete isolation between modules
  44. OOP is not about Objects http://3.bp.blogspot.com/-MwiEp-63Qro/TrQvxNtQbBI/AAAAAAAABNc/6c8bAI0kdAM/s1600/facteur.jpg

  45. It’s about the Message.

  46. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg Objects: what the system is. Messages: what the system

    does.
  47. http://x4.fjcdn.com/comments/Oh+_a70c957887dd1e4f713fb14db1dc582a.jpg Likely built with OOP

  48. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg NASA basically rewrote Erlang

  49. http://cdn.cantechletter.com/wp-content/uploads/2012/09/NASA-Mars-Rover.jpg "Erlang might be the only object oriented language” -

    Joe Armstrong
  50. Person calls Pencil#write 1/2 Developer’s point of view Person Pencil

    Pen
  51. 2/2 Object’s point of view someone someone else pay() pay()

    someone else
  52. None
  53. None
  54. Objects = 2 Complexity = 1

  55. Objects = 3 Complexity = 3

  56. Objects = 6 Complexity = ?

  57. Objects = 6 Complexity = 15

  58. How to stop complexity

  59. How to stop wasting time complexity

  60. How to stop wasting money wasting time complexity

  61. “The key to scalability lies in how messaging is actually

    done. The key to abstraction and compactness lies in a felicitous combination of design and mathematics." ! - Alan Kay
  62. Constructal Law

  63. http://upload.wikimedia.org/wikipedia/commons/f/f6/Bright_green_tree_-_Waikato.jpg

  64. http://hqwallpapersplus.com/wp-content/uploads/2013/09/Snowflake-Pictures-11.jpg

  65. http://readywisconsin.wi.gov/lightning/images/Lightning_1.jpg

  66. http://marjorymejia.com/wp-content/uploads/2012/10/800px-Mouths_of_amazon_geocover_1990.png

  67. http://lh3.ggpht.com/-MgYN_UYAeCQ/S3xhh3CvNlI/AAAAAAAAAIU/j9rFK8ew7cE/900898-Resin%2520cast%2520human%2520lungs%2520and%2520bronchial%2520tree.jpg

  68. http://www.spatialcomplexity.info/files/2012/12/morphology-map.png

  69. Objects = 6 Complexity = 15

  70. Objects = 7 Complexity = 8

  71. C O Before After Architecture comparison

  72. Example Module Module Module Computer Computer Computer

  73. Danger, Will Robinson! Módulo Módulo Módulo A B

  74. Effects ! 1. decreased complexity 2. simpler code 3. lower

    cognitive load 4. less wasted $$$
  75. class ImportationService def process orgs = Organizations.new(client).import orgs.each do |org|

    projects = Projects.new(org).import end projects.each do |project| Members.new(client).import Stories.new(client).import end end end Before
  76. module RemoteService class Organizations def initialize(remote_client) @client = remote_client end

    def import import_organizations Projects.new(@client).import end ! private ! def import_organizations organizations = @client.organizations OrganizationsTable.new(organizations).save end end end After
  77. module RemoteService class Projects def initialize(remote_client) @client = remote_client end

    def import import_projects Members.new(@client).import Stories.new(@client).import end ! private ! def import_projects projects = @client.projects ProjectsTable.new(projects).save end end end
  78. module RemoteService class Projects def initialize(remote_client) @client = remote_client end

    def import import_projects Members.new(@client).import Stories.new(@client).import unless @client.github? end ! private ! def import_projects projects = @client.projects ProjectsTable.new(projects).save end end end What now?
  79. module PivotalTracker class Client def organizations HTTParty.get(‘url’).map { |i| Response::Organization.new(i)

    } end ! def projects HTTParty.get(‘url2’).map { |i| Response::Project.new(i) } end ! def members HTTParty.get(‘url3’).map { |i| Response::Member.new(i) } end ! def stories HTTParty.get(‘url4’).map { |i| Response::Story.new(i) } end end end
  80. module Github class Client def organizations HTTParty.get(‘url’).map { |i| Response::Organization.new(i)

    } end ! ! ! ! ! ! ! ! ! ! ! ! end end
  81. module Github class Client def organizations HTTParty.get(‘url’).map { |i| Response::Organization.new(i)

    } end ! def projects HTTParty.get(‘url2’).map { |i| Response::Project.new(i) } end ! ! ! ! ! ! ! ! end end
  82. module Github class Client def organizations HTTParty.get(‘url’).map { |i| Response::Organization.new(i)

    } end ! def projects HTTParty.get(‘url2’).map { |i| Response::Project.new(i) } end ! def members HTTParty.get(‘url3’).map { |i| Response::Member.new(i) } end ! ! ! ! end end
  83. module Github class Client def organizations HTTParty.get(‘url’).map { |i| Response::Organization.new(i)

    } end ! def projects HTTParty.get(‘url2’).map { |i| Response::Project.new(i) } end ! def members HTTParty.get(‘url3’).map { |i| Response::Member.new(i) } end ! def stories [] end end end
  84. Effects ! 1. flexible code 2. less changes 3. Open/Closed

    principle 4. less wasted $$$
  85. What about debugging?

  86. What about debugging? Module Module Module Computer Computer Computer

  87. Binary Search Module Module Module Computer Computer Computer

  88. Binary Search Module Module Computer Computer Computer has the bug

  89. Instrumentation Module Computer Tests

  90. Write great code

  91. Embrace OO

  92. “It (OOP) can be done in Smalltalk and in LISP”

    Alan Kay
  93. Thank you!

  94. Resources • http://computinged.wordpress.com/2010/09/15/alan-kay-on-motis-objects-ever-cacm-article/ • http://jlouisramblings.blogspot.com/2012/08/getting-25-megalines-of-code-to-behave.html