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

Treating Objects Like People (Baruco, Sept 2013)

Cdf378de2284d8acf137122e541caa28?s=47 mattwynne
September 14, 2013

Treating Objects Like People (Baruco, Sept 2013)

Cucumber core developer Matt Wynne uses the example of re-developing Cucumber's internals to explain important lessons about object-oriented design.

Cdf378de2284d8acf137122e541caa28?s=128

mattwynne

September 14, 2013
Tweet

Transcript

  1. TREATING OBJECTS LIKE PEOPLE @mattwynne | @baruco | Setiembre 2013

  2. (c) David Shrigley

  3. None
  4. 2008

  5. None
  6. 2012

  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. Feature: Update card details Need to be able to update

    my card, e.g. if I decide to use a different one for billing. Scenario: Update card details successfully Given I have started a paid subscription on the pro plan When I choose to update which card is billed Then I should see that my card details have been saved Scenario: Use a bad card Given I have started a paid subscription on the pro plan When I try to change to an invalid card Then I should see that my card has been declined
  14. Feature Scenario Step * * Formatter

  15. Result

  16. Feature Scenario Formatter Step accept(self) before_feature accept(formatter) before_scenario accept(formatter) before_step

    after_step after_scenario after_feature execute(step)
  17. Feature: Update card details Need to be able to update

    my card, e.g. if I decide to use a different one for billing. Scenario: Update card details successfully Given I have started a paid subscription on the pro plan When I choose to update which card is billed Then I should see that my card details have been saved Scenario: Use a bad card Given I have started a paid subscription on the pro plan When I try to change to an invalid card Then I should see that my card has been declined
  18. Feature: Update card details Need to be able to update

    my card, e.g. if I decide to use a different one for billing. Scenario: Update card details successfully Given I have started a paid subscription on the pro plan When I choose to update which card is billed Then I should see that my card details have been saved Scenario: Use a bad card Given I have started a paid subscription on the pro plan When I try to change to an invalid card Then I should see that my card has been declined
  19. Feature: Update card details Need to be able to update

    my card, e.g. if I decide to use a different one for billing. Background: Given I have started a paid subscription on the pro plan Scenario: Update card details successfully When I choose to update which card is billed Then I should see that my card details have been saved Scenario: Use a bad card When I try to change to an invalid card Then I should see that my card has been declined
  20. Feature Scenario Step * * Background Step * 0..1

  21. Feature: Update card details Need to be able to update

    my card, e.g. if I decide to use a different one for billing. Scenario Outline: Update card details Given I have started a paid subscription on the pro plan When I update my card details with a <card status> card Then I should see "<message>" Examples: | card status | message | | valid | Your card details have been saved. | | expired | This card has expired. | | stolen | The police are on their way. |
  22. Feature Scenario Step * * Background Step * 0..1 Scenario

    Outline Step * * Example *
  23. module Cucumber module Ast class Background def accept(visitor) return if

    @already_visited visitor.visit_background(self) do comment.accept(visitor) visitor.visit_background_name(@keyword, name, file_colon_li with_visitor(feature_elements.first || self, visitor) do visitor.runtime.before(hook_context) skip_invoke! if failed? step_invocations.accept(visitor) @failed = step_invocations.any? do |step_invocation| step_invocation.exception || step_invocation.status != :passed end if @failed || feature_elements.empty? visitor.runtime.after(hook_context) end end end @already_visited = true end
  24. Our First Mistake: Data-Centric Domain Model

  25. None
  26. Problem Domain Solution Domain

  27. "Model the problem domain and the solution will take care

    of itself." DAVID WEST, OBJECT THINKING
  28. 1967

  29. SIMULA 67 1967 http://www.jot.fm/issues/issue_2002_09/eulogy/

  30. "It should be problem oriented and not computer oriented, even

    if this implies an appreciable increase in the amount of work that has to be done by the computer" SIMULA 67 1967 http://www.jot.fm/issues/issue_2002_09/eulogy/
  31. None
  32. 1979

  33. C++ 1979 "SIMULA's class-based system was a huge plus, but

    it's run-time performance was hopeless."
  34. SMALLTALK-80 Called "Smalltalk"--as in "programming should be a matter of

    ..." [Smalltalk] and "children should program in ..." [Smalltalk]. -- Alan Kay 1980
  35. SIMULA 67 1967 C++ 1979 Smalltalk-80 1980

  36. Two philosophies

  37. Two cultures

  38. C++ Smalltalk-80

  39. "Good" OOP "Bad" OOP FOCUS ON DATA FOCUS ON MESSAGES

    FOCUS ON BEHAVIOUR, RESPONSIBILITIES FOCUS ON STRUCTURE, LAYERS ABSORBED IN THE PROBLEM DISTRACTED BY THE SOLUTION CULTURE OF FLEXIBILITY, COLLABORATION, FUN, CHAOS CULTURE OF FORMALITY, HIERARCHY, CENTRALISED CONTROL
  40. None
  41. 2.0

  42. None
  43. Our first fix: A responsibility-centric model

  44. Compiler Runner Parser Report

  45. A design principle: Tell objects, ask values* * (thank GOOS)

  46. Compiler Runner Parser feature scenario step test_case step scenario step

    step test_case
  47. Compiler Runner test_case Report before_test_case(case) after_test_case(case, result) before_test_step(step) after_test_step(step, result)

    execute(step)
  48. LESS STATE, LESS BUGS

  49. YOUR PROGRAMS ARE PROBABLY TOO STUPID TO BE ALLOWED TO

    REMEMBER STUFF
  50. So remember... MODEL ACTIVITY, THEN PUSH DATA THROUGH THAT MODEL

    MAKE YOUR DATA IMMUTABLE TELL OBJECTS, ASK VALUES TREAT OBJECTS LIKE PEOPLE
  51. http://cucumber.pro