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. VI

  2. 6

  3. 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
  4. 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
  5. 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
  6. 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
  7. 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™
  8. Component 1 Component 2 Component 3 Component n Message Queue

    Component 4 Component 5 Component 6 Component z
  9. “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
  10. 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
  11. 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
  12. 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
  13. 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?
  14. 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
  15. 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
  16. 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
  17. 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