The Building Blocks
                     of Modularity

                               Jim Weirich
                       ...
Tech Interview
“What Technical Books
  Have You Read
    Recently?”
“What do you look for
  in a good design?”
Ummm?
Gravity       Electromagnetism




Strong Nuclear    Weak Nuclear
Gravity       Electromagnetism


         Grand
         Unified
          Field
         Theory
Strong Nuclear    Weak Nuc...
Some Principles ...
• SOLID
• Law of Demeter
• DRY
• Small Methods
• Design by Contract
Some Principles ...
 • SOLID Unified Theory
Grand
 • Law of Demeter
              of
 • DRY Development
Software
 • Small M...
The Grand Unified
                     Theory of Software
                       Development
                              ...
1978
Coupling & Cohesion
No

           Types of
Coupling

  Data

           Coupling
Coupling

 Stamp
Coupling

 Control
Coupling

External
Coupl...
No

                      Types of
  Less     Coupling

Coupling     Data

                      Coupling
 (good)    Coupl...
No
Coupling

  Data
Coupling

 Stamp
Coupling

 Control
Coupling

External
Coupling

Common
Coupling

Content
Coupling
No
Coupling

  Data
Coupling

 Stamp
Coupling

 Control
Coupling

External
Coupling

Common
Coupling

Content
Coupling
No
Coupling




           }
  Data
Coupling
               Local Data
 Stamp
Coupling

 Control
Coupling




           }...
No
             Coupling




                        }
 Simple        Data
             Coupling
  Data
                  ...
No
Coupling

  Data
Coupling

 Stamp
Coupling

 Control
Coupling

External
Coupling

Common
Coupling

Content
Coupling
Control Coupling
• Method has a “flag” parameter
• The flag controls which algorithm to use
Control Coupling
 • Method has a “flag” parameter
 • The flag controls which algorithm to use
• Symptoms
 • The word “OR” in...
Control Coupling

Array.instance_methods
Control Coupling

Array.instance_methods
Array.instance_methods(true)
Array.instance_methods(false)
Control Coupling

Array.instance_methods
Array.instance_methods(true)
Array.instance_methods(false)

     ... the instance...
Control Coupling

Array.instance_methods
Array.instance_methods(true)
Array.instance_methods(false)

     ... the instance...
Another Example?
Control Coupling


Customer.find(:first, ...)
Customer.find(:all, ...)
Control Coupling
                   Returns object


Customer.find(:first, ...)
Customer.find(:all, ...)



              ...
Myer’s Classifications
     were ‘OK’
Failed to extend
well to Objects and
Dynamic Languages
1996
Connascence

1. The common birth of two or more at the
   same time; production of two or more
   together.
2. That which ...
Connascence

Two pieces of software share
connascence when a changes in
one requires a corresponding
change in the other.
CoN
class Customer
  def email
    ...
  end
end

                 def send_mail(customer)
                   customer.email
 ...
class Customer
  def email
    ...
  end
end

                 def send_mail(customer)
                   customer.email
 ...
Connascence of Name
class Customer
  def email
    ...
  end
end

                 def send_mail(customer)
               ...
Connascence of Name
create_table “customers” do |t|
  t.column :email, :string
  ...
end




                       def se...
Connascence of Name
                 Another example?
class Customer
  def email
    ...
  end
end

                 def s...
Connascence of Name
                 Another example?
class Customer



                 X
  def email
    ...
  end
end

...
Connascence of Name
                 Another example?
class Customer
  def email
    ...
  end
end

                  def ...
Locality Matters
Rule of Locality
  Stronger
 Connascence
                 Weaker
               Connascence
Rule of Locality

  As the distance between
software elements increases,
    use weaker forms of
       connascence.
CoP
:orders => {
                  “3” => “1”,
                  “5” => “2”
                }



Translate params hash
       ...
def process_orders(list_of_pairs)
  list_of_pairs.each do |order, expedite|
    # handle an order
  end
end


 Order of th...
class OrdersController
  def build_order_list(params)
      [order, flag]
  end
end


       class Orders
         def pro...
Connascence of Position
class OrdersController
  def build_order_list(params)
      [order, flag]
  end
end


       class...
Consider
Low Degree of CoP


    [ order, expedite ]
High Degree of CoP

[
    order, expedite, confirmation_number,
    ordered_date, expiration, special
]
CoP               CoN
class OrderDisposition
  attr_reader :order,
    :expedite,
    :confirmation_number,
    :ordered_d...
Degree Matters
CoN < CoP
Rule of Degree


Convert high degrees of connascence
                into
   weaker forms of connascence
Another Example?
Customers.find(
  [“last_name = ?”, “Weirich”], “age”)




   def find(conditions, ordered_by)
     ...
   end
Customers.find(
  [“last_name = ?”, “Weirich”], “age”,
  12, 24, [‘first_name’, ‘last_name’])




   def find(conditions, ...
CoP                  CoN
Customers.find(
  :conditions => [“last_name = ?”, “Weirich”],
  :order_by => “age”,
  :limit => ...
Another Example?
Connascence of Position

def test_user_can_do_something_interesting
  user = User.find(:first)
  ...
end
Connascence of Position

def test_user_can_do_something_interesting
  user = User.find_by_name(“Jim”)
  ...
end
CoM
<input type=quot;checkboxquot; value=quot;2quot; />
<input type=quot;checkboxquot; value=quot;1quot; />
<input type=quot;checkboxquot; value=quot;2quot; />
<input type=quot;checkboxquot; value=quot;1quot; />
<input type=quot;checkboxquot; value=quot;2quot; />
<input type=quot;checkboxquot; value=quot;1quot; />




if params[:med...
Connascence of Meaning
<input type=quot;checkboxquot; value=quot;2quot; />
<input type=quot;checkboxquot; value=quot;1quot...
Connascence of Meaning


MED_GIVEN = quot;1quot;
MED_NOT_GIVEN = quot;2quot;
CoM                   CoN
MED_GIVEN = quot;1quot;
MED_NOT_GIVEN = quot;2quot;



<input type=quot;checkboxquot; value=quot...
CoM                   CoN
MED_GIVEN = “1”
MED_NOT_GIVEN = “2”



<input type=quot;checkboxquot; value=quot;<%= MED_GIVEN %...
CN
Revisit

MED_GIVEN = quot;1quot;

MED_NOT_GIVEN = quot;2quot;
MED_GIVEN = quot;1quot;

MED_NOT_GIVEN = quot;2quot;
X
MED_GIVEN = quot;1quot;

MED_NOT_GIVEN = quot;1quot;
Contranascence




      X
MED_GIVEN = quot;1quot;

MED_NOT_GIVEN = quot;1quot;
Another Example?
Contranascence

My XML Library

class Node
  ...
end
Contranascence

My XML Library   Your Graphing Library

class Node         class Node
  ...                ...
end        ...
Contranascence

My XML Library   Your Graphing Library

class Node         class Node
  ...                ...
end        ...
Contranascence

My XML Library   Your Graphing Library

module MyXml     module YourGraphing
  class Node       class Node...
Contranascence

irb/slex.rb:92:                 class   Node
tkextlib/blt/tree.rb:15:        class   Node   <   TkObject
t...
Another Example?
Contranascence

My XML Library   Your Graphing Library

module Kernel      module Kernel
  def to_node        def to_node
...
Contranascence




          X
My XML Library   Your Graphing Library

module Kernel      module Kernel
  def to_node     ...
Contranascence

Selector Namespaces
      (Ruby 2 ?)
CoA
add_check_digit(“31415972”)     “314159728”




         check?(“ 314159728”)     true

         check?(“ 314159723”)     ...
def add_check_digit(digits)
  check_sum = digits.split(//).
    inject(0) { |r, n| r + n.to_i } % 10
  digits + ((10 - che...
def add_check_digit(digits)
  check_sum = digits.split(//).
    inject(0) { |r, n| r + n.to_i } % 10
  digits + ((10 - che...
Connascence of Algorithm
def add_check_digit(digits)
  check_sum = digits.split(//).
    inject(0) { |r, n| r + n.to_i } %...
CoA                 CoN
def add_check_digit(digits)
  digits + ((10 - check_sum(digits)) % 10).to_s
end

def check?(digits...
DRY
def add_check_digit(digits)
  digits + ((10 - check_sum(digits)) % 10).to_s
end

def check?(digits)
  check_sum(digits...
Summary
Connascence
•                                       •
    Static                                  Dynamic
    •           ...
References
•   What Every Programmer Should Know About Object Oriented
    Design, Meilir Page-Jones
•   Fundamentals of O...
Questions?
Thank You!
git://github.com/jimweirich/presentation_connascence.git


              Copyright 2009 by Jim Weirich, Some Ri...
The Building Blocks Of Modularity
The Building Blocks Of Modularity
The Building Blocks Of Modularity
Upcoming SlideShare
Loading in …5
×

The Building Blocks Of Modularity

2,347 views

Published on

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,347
On SlideShare
0
From Embeds
0
Number of Embeds
8
Actions
Shares
0
Downloads
57
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

The Building Blocks Of Modularity

  1. 1. The Building Blocks of Modularity Jim Weirich Chief Scientist EdgeCase LLC @jimweirich Copyright 2009, Jim Weirich All Rights Reserved
  2. 2. Tech Interview
  3. 3. “What Technical Books Have You Read Recently?”
  4. 4. “What do you look for in a good design?”
  5. 5. Ummm?
  6. 6. Gravity Electromagnetism Strong Nuclear Weak Nuclear
  7. 7. Gravity Electromagnetism Grand Unified Field Theory Strong Nuclear Weak Nuclear
  8. 8. Some Principles ... • SOLID • Law of Demeter • DRY • Small Methods • Design by Contract
  9. 9. Some Principles ... • SOLID Unified Theory Grand • Law of Demeter of • DRY Development Software • Small Methods • Design by Contract
  10. 10. The Grand Unified Theory of Software Development Jim Weirich Chief Scientist EdgeCase LLC @jimweirich Copyright 2009, Jim Weirich All Rights Reserved
  11. 11. 1978
  12. 12. Coupling & Cohesion
  13. 13. No Types of Coupling Data Coupling Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
  14. 14. No Types of Less Coupling Coupling Data Coupling (good) Coupling Stamp Coupling Control Coupling External Coupling Common More Coupling Coupling Content (bad) Coupling
  15. 15. No Coupling Data Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
  16. 16. No Coupling Data Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
  17. 17. No Coupling } Data Coupling Local Data Stamp Coupling Control Coupling } External Coupling Global Data Common Coupling Content Coupling
  18. 18. No Coupling } Simple Data Coupling Data Local Data Stamp Coupling Control Coupling } External Structured Coupling Data Global Data Common Coupling Content Coupling
  19. 19. No Coupling Data Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
  20. 20. Control Coupling • Method has a “flag” parameter • The flag controls which algorithm to use
  21. 21. Control Coupling • Method has a “flag” parameter • The flag controls which algorithm to use • Symptoms • The word “OR” in description • Flag value is arbitrary and not related to problem domain.
  22. 22. Control Coupling Array.instance_methods
  23. 23. Control Coupling Array.instance_methods Array.instance_methods(true) Array.instance_methods(false)
  24. 24. Control Coupling Array.instance_methods Array.instance_methods(true) Array.instance_methods(false) ... the instance methods in mod are returned, otherwise the methods in mod and mod's superclasses are returned.
  25. 25. Control Coupling Array.instance_methods Array.instance_methods(true) Array.instance_methods(false) ... the instance methods in mod are returned, otherwise the methods in mod and mod's superclasses are returned.
  26. 26. Another Example?
  27. 27. Control Coupling Customer.find(:first, ...) Customer.find(:all, ...)
  28. 28. Control Coupling Returns object Customer.find(:first, ...) Customer.find(:all, ...) Returns list of objects
  29. 29. Myer’s Classifications were ‘OK’
  30. 30. Failed to extend well to Objects and Dynamic Languages
  31. 31. 1996
  32. 32. Connascence 1. The common birth of two or more at the same time; production of two or more together. 2. That which is born or produced with another. 3. The act of growing together.
  33. 33. Connascence Two pieces of software share connascence when a changes in one requires a corresponding change in the other.
  34. 34. CoN
  35. 35. class Customer def email ... end end def send_mail(customer) customer.email ... end
  36. 36. class Customer def email ... end end def send_mail(customer) customer.email ... end
  37. 37. Connascence of Name class Customer def email ... end end def send_mail(customer) customer.email ... end
  38. 38. Connascence of Name create_table “customers” do |t| t.column :email, :string ... end def send_mail(customer) customer.email ... end
  39. 39. Connascence of Name Another example? class Customer def email ... end end def send_mail(customer) customer.email ... end
  40. 40. Connascence of Name Another example? class Customer X def email ... end end def send_mail(customer) customer.email ... end
  41. 41. Connascence of Name Another example? class Customer def email ... end end def send_mail(customer) customer.email ... end
  42. 42. Locality Matters
  43. 43. Rule of Locality Stronger Connascence Weaker Connascence
  44. 44. Rule of Locality As the distance between software elements increases, use weaker forms of connascence.
  45. 45. CoP
  46. 46. :orders => { “3” => “1”, “5” => “2” } Translate params hash to A List of Pairs [ [ Order.find(3), true ], [ Order.find(5), false ], ]
  47. 47. def process_orders(list_of_pairs) list_of_pairs.each do |order, expedite| # handle an order end end Order of the data within the pair is significant [ [ Order.find(3), true ], [ Order.find(5), false ], ]
  48. 48. class OrdersController def build_order_list(params) [order, flag] end end class Orders def process_orders(pairs) pairs.each do |order, flag| ... end end end
  49. 49. Connascence of Position class OrdersController def build_order_list(params) [order, flag] end end class Orders def process_orders(pairs) pairs.each do |order, flag| ... end end end
  50. 50. Consider
  51. 51. Low Degree of CoP [ order, expedite ]
  52. 52. High Degree of CoP [ order, expedite, confirmation_number, ordered_date, expiration, special ]
  53. 53. CoP CoN class OrderDisposition attr_reader :order, :expedite, :confirmation_number, :ordered_date, :expiration, :special ... end
  54. 54. Degree Matters
  55. 55. CoN < CoP
  56. 56. Rule of Degree Convert high degrees of connascence into weaker forms of connascence
  57. 57. Another Example?
  58. 58. Customers.find( [“last_name = ?”, “Weirich”], “age”) def find(conditions, ordered_by) ... end
  59. 59. Customers.find( [“last_name = ?”, “Weirich”], “age”, 12, 24, [‘first_name’, ‘last_name’]) def find(conditions, ordered_by, limit, offset, selected) ... end
  60. 60. CoP CoN Customers.find( :conditions => [“last_name = ?”, “Weirich”], :order_by => “age”, :limit => 12, :offset => 24, :select => [‘first_name’, ‘last_name’]) def find(options={}) ... end
  61. 61. Another Example?
  62. 62. Connascence of Position def test_user_can_do_something_interesting user = User.find(:first) ... end
  63. 63. Connascence of Position def test_user_can_do_something_interesting user = User.find_by_name(“Jim”) ... end
  64. 64. CoM
  65. 65. <input type=quot;checkboxquot; value=quot;2quot; /> <input type=quot;checkboxquot; value=quot;1quot; />
  66. 66. <input type=quot;checkboxquot; value=quot;2quot; /> <input type=quot;checkboxquot; value=quot;1quot; />
  67. 67. <input type=quot;checkboxquot; value=quot;2quot; /> <input type=quot;checkboxquot; value=quot;1quot; /> if params[:med][id] == quot;1quot; mark_given(id) elsif params[:med][id] == quot;2quot; mark_not_given(id) end
  68. 68. Connascence of Meaning <input type=quot;checkboxquot; value=quot;2quot; /> <input type=quot;checkboxquot; value=quot;1quot; /> if params[:med][id] == quot;1quot; mark_given(id) elsif params[:med][id] == quot;2quot; mark_not_given(id) end
  69. 69. Connascence of Meaning MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;2quot;
  70. 70. CoM CoN MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;2quot; <input type=quot;checkboxquot; value=quot;<%= MED_GIVEN %>quot; /> <input type=quot;checkboxquot; value=quot;<%= MED_NOT_GIVEN %>quot; /> if params[:med][id] == MED_GIVEN mark_given(id) elsif params[:med][id] == MED_NOT_GIVEN mark_not_given(id) end
  71. 71. CoM CoN MED_GIVEN = “1” MED_NOT_GIVEN = “2” <input type=quot;checkboxquot; value=quot;<%= MED_GIVEN %>quot; /> <input type=quot;checkboxquot; value=quot;<%= MED_NOT_GIVEN %>quot; /> if params[:med][id] == MED_GIVEN mark_given(id) elsif params[:med][id] == MED_NOT_GIVEN mark_not_given(id) end
  72. 72. CN
  73. 73. Revisit MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;2quot;
  74. 74. MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;2quot;
  75. 75. X MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;1quot;
  76. 76. Contranascence X MED_GIVEN = quot;1quot; MED_NOT_GIVEN = quot;1quot;
  77. 77. Another Example?
  78. 78. Contranascence My XML Library class Node ... end
  79. 79. Contranascence My XML Library Your Graphing Library class Node class Node ... ... end end
  80. 80. Contranascence My XML Library Your Graphing Library class Node class Node ... ... end end
  81. 81. Contranascence My XML Library Your Graphing Library module MyXml module YourGraphing class Node class Node ... ... end end end end
  82. 82. Contranascence irb/slex.rb:92: class Node tkextlib/blt/tree.rb:15: class Node < TkObject tkextlib/blt/treeview.rb:18: class Node < TkObject tkextlib/blt/treeview.rb:966: class Node < TkObject tkextlib/bwidget/tree.rb:13: class Node < TkObject tkextlib/bwidget/tree.rb:262: class Node xmlrpc/parser.rb:17: class Node yaml/syck.rb:14: class Node
  83. 83. Another Example?
  84. 84. Contranascence My XML Library Your Graphing Library module Kernel module Kernel def to_node def to_node ... ... end end end end
  85. 85. Contranascence X My XML Library Your Graphing Library module Kernel module Kernel def to_node def to_node ... ... end end end end
  86. 86. Contranascence Selector Namespaces (Ruby 2 ?)
  87. 87. CoA
  88. 88. add_check_digit(“31415972”) “314159728” check?(“ 314159728”) true check?(“ 314159723”) false
  89. 89. def add_check_digit(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 digits + ((10 - check_sum) % 10).to_s end def check?(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 check_sum == 0 end
  90. 90. def add_check_digit(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 digits + ((10 - check_sum) % 10).to_s end def check?(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 check_sum == 0 end
  91. 91. Connascence of Algorithm def add_check_digit(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 digits + ((10 - check_sum) % 10).to_s end def check?(digits) check_sum = digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 check_sum == 0 end
  92. 92. CoA CoN def add_check_digit(digits) digits + ((10 - check_sum(digits)) % 10).to_s end def check?(digits) check_sum(digits) == 0 end def check_sum(digits) digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 end
  93. 93. DRY def add_check_digit(digits) digits + ((10 - check_sum(digits)) % 10).to_s end def check?(digits) check_sum(digits) == 0 end def check_sum(digits) digits.split(//). inject(0) { |r, n| r + n.to_i } % 10 end
  94. 94. Summary
  95. 95. Connascence • • Static Dynamic • • Connascence of Name Connascence of Execution • • Connascence of Type Connascence of Timing • • Connascence of Meaning Connascence of Value • • Connascence of Algorithm Connascence of Identity • • Connascence of Position Contranascence Rules • Rule of Locality • Rule of Degree
  96. 96. References • What Every Programmer Should Know About Object Oriented Design, Meilir Page-Jones • Fundamentals of Object-Oriented Design in UML, Meilir Page-Jones • Composite/Structured Design, Glenford Myers • Reliable Software Through Composite Design, Glenford Myers • Agile Software Development, Principles, Patterns, and Practices, Robert Martin • Object-Oriented Software Construction, Bertrand Meyer • The Pragmatic Programmer: From Journeyman to Master, Andy Hunt & Dave Thomas
  97. 97. Questions?
  98. 98. Thank You! git://github.com/jimweirich/presentation_connascence.git Copyright 2009 by Jim Weirich, Some Rights Reserved

×