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

A Missing Part of OOP

A Missing Part of OOP

#dcimeetup

Kentaro Kuribayashi

March 08, 2013
Tweet

More Decks by Kentaro Kuribayashi

Other Decks in Technology

Transcript

  1. DCI

  2. “In the old days of FORTRAN and Pascal, I could

    convert a Use Case scenario into code, give it to my office mate with the scenario description, and ask him or her to desk check it. Today, after the polymorphism and object orientation of 1967, I can't do that. Our ability to reason about systems has been lost.” http://qconlondon.com/dl/qcon-london-2010/slides/JimO.Coplien_TheDCIArchitectureLeanAndAgileAtTheCodeLevel.pdf
  3. class MoneyTransfer def initialize(source, destination) @source = source @source.extend(Transferrer) @destination

    = destination end def execute(amount) @source.transfer_to(@destination, amount) end module Transferrer def transfer_to(destination, amount) self.balance -= amount destination.balance += amount end end end Methodful Role
  4. • Interaction of objects happens in a certain context •

    Methodful role holds methods to be added • Role is combined to object dynamically at runtime
  5. class FooTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination =

    destination end ... class BarTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination = destination end ... class BazTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination = destination end ... module Transferrer ... end
  6. • Methods in roles can be called from anywhere. •

    When we read the code, it’s such a bad dream of “goto”- like programming, isn’t it?
  7. module Repository include MethodRepository insert :method1, in: %w[Foo Bar] do;

    end insert :method2, in: %w[Baz] do; end end class Foo; end class Bar; end class Baz; end class Qux; end
  8. Foo.extend(Repository) Bar.extend(Repository) Baz.extend(Repository) Qux.extend(Repository) Foo.respond_to?(:method1) #=> true Bar.respond_to?(:method1) #=> true

    Baz.respond_to?(:method1) #=> false Qux.respond_to?(:method1) #=> false Foo.respond_to?(:method2) #=> false Bar.respond_to?(:method2) #=> false Baz.respond_to?(:method2) #=> true Qux.respond_to?(:method2) #=> false
  9. foo = Foo.new; foo.extend(Repository) bar = Bar.new; bar.extend(Repository) baz =

    Baz.new; bar.extend(Repository) qux = Qux.new; qux.extend(Repository) foo.respond_to?(:method1) #=> true bar.respond_to?(:method1) #=> true baz.respond_to?(:method1) #=> false qux.respond_to?(:method1) #=> false foo.respond_to?(:method2) #=> false bar.respond_to?(:method2) #=> false baz.respond_to?(:method2) #=> true qux.respond_to?(:method2) #=> false
  10. Foo.send(:include, Repository) Bar.send(:include, Repository) Baz.send(:include, Repository) Qux.send(:include, Repository) Foo.new.respond_to?(:method1) #=>

    true Bar.new.respond_to?(:method1) #=> true Baz.new.respond_to?(:method1) #=> false Qux.new.respond_to?(:method1) #=> false Foo.new.respond_to?(:method2) #=> false Bar.new.respond_to?(:method2) #=> false Baz.new.respond_to?(:method2) #=> true Qux.new.respond_to?(:method2) #=> false
  11. module Extendable include MethodRepository extendable_by 'Hoge' end module Includable include

    MethodRepository includable_by 'Hoge' end class Hoge; end class Fuga; end
  12. class FooTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination =

    destination end ... class BarTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination = destination end ... class BazTransfer def initialize(source, destination) @source = source.extend(Transferrer) @destination = destination end ... module Transferrer extendable_by ‘Account’ ... end × Limits extending when class doesn’t comply with definition of the module.
  13. • Commonalizes methods in a usual way • But limits

    them where to be inserted • Methods won’t be called from somewhere we don’t know. So, we won’t be burdened to dig around the code.
  14. • DCI is worth considering • We need commonalization even

    with DCI • Commonalization can cause “goto”-like programming without any limitation • method_repository can help you.