Connascence Key
Connascence Key
Tech Interview
Ummm?
Maxwells Equations
Unied!
Electric Fields + Magnetic Fields
Electromagnetism
His [Maxwells] work in producing a unied model of electromagnetism is considered to be one of the greatest advances in physics. -- Wikipedia
- + + - + -+ +- + - + +- +- + - ++ -
Ernest Rutherford
1909
Unexpected Reections
++ - + -
Gravity
Electromagnetism
Strong Nuclear
Weak Nuclear
Gravity
Electromagnetism
SOLID Unied Theory Grand Law of Demeter of DRY Development Software Small Methods Design by Contract
1978
No Coupling Data Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
Types of Coupling
Types of Coupling
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 Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
} }
Local Data
Global Data
No Coupling
Simple Data
} }
Local Data
Structured Data
Global Data
No Coupling Data Coupling Stamp Coupling Control Coupling External Coupling Common Coupling Content Coupling
Control Coupling
Method has a ag parameter The ag controls which algorithm to use
Control Coupling
Method has a ag parameter The ag controls which algorithm to use Symptoms The word OR in description Flag value is arbitrary and not related to
problem domain.
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 methods in mod are returned, otherwise the methods in mod and mod's superclasses are returned.
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.
Another Example?
Control Coupling
Control Coupling
Returns object Customer.find(:first, ...) Customer.find(:all, ...)
1996
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.
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 ... end
class Customer def email ... end end def send_mail(customer) customer.email ... end
Connascence of Name
class Customer def email ... end end def send_mail(customer) customer.email ... end
Connascence of Name
create_table customers do |t| t.column :email, :string ... end
Connascence of Name
class Customer def email ... end end
Another example?
Connascence of Name
class Customer def email ... end end
Another example?
Connascence of Name
class Customer def email ... end end
Another example?
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
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
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
Consider
CoP
CoN
class OrderDisposition attr_reader :order, :expedite, :confirmation_number, :ordered_date, :expiration, :special ... end
Degree Matters
Rule of Degree
Convert high degrees of connascence into weaker forms of connascence
Another Example?
CoP
CoN
Customers.find( :conditions => [last_name = ?, Weirich], :order_by => age, :limit => 12, :offset => 24, :select => [first_name, last_name])
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
Connascence of Meaning
<input type="checkbox" value="2" /> <input type="checkbox" value="1" />
Connascence of Meaning
MED_GIVEN = "1" MED_NOT_GIVEN = "2"
CoM
MED_GIVEN = "1" MED_NOT_GIVEN = "2"
CoN
<input type="checkbox" value="<%= MED_GIVEN %>" /> <input type="checkbox" value="<%= MED_NOT_GIVEN %>" />
CoM
MED_GIVEN = 1 MED_NOT_GIVEN = 2
CoN
<input type="checkbox" value="<%= MED_GIVEN %>" /> <input type="checkbox" value="<%= MED_NOT_GIVEN %>" />
CN
Revisit
MED_GIVEN = "1" MED_NOT_GIVEN = "2"
MED_GIVEN = "1"
MED_NOT_GIVEN = "1"
Contranascence
MED_GIVEN = "1"
MED_NOT_GIVEN = "1"
Another Example?
Contranascence
My XML Library
class Node ... end
Contranascence
My XML Library
class Node ... end
Contranascence
My XML Library
class Node ... end
Contranascence
My XML Library
module MyXml class Node ... end end
Contranascence
irb/slex.rb:92: tkextlib/blt/tree.rb:15: tkextlib/blt/treeview.rb:18: tkextlib/blt/treeview.rb:966: tkextlib/bwidget/tree.rb:13: tkextlib/bwidget/tree.rb:262: xmlrpc/parser.rb:17: yaml/syck.rb:14: class class class class class class class class Node Node Node Node Node Node Node Node < < < < TkObject TkObject TkObject TkObject
Another Example?
Contranascence
My XML Library
module Kernel def to_node ... end end
Contranascence
My XML Library
module Kernel def to_node ... end end
Contranascence
Selector Namespaces
(Ruby 2 ?)
CoA
add_check_digit(31415972)
314159728
true false
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 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
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
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
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
CoT
The Setup
@amount += 1 @amount += 1
23
Step 1
@amount += 1 @amount += 1
1
23
23
Step 2
@amount += 1 @amount += 1
2
23 23
23
Step 3
@amount += 1 @amount += 1
24
3
23 24
Step 4
@amount += 1 @amount += 1
24
Should be 25 at this point!
24 24
4
Race Condition
@amount += 1 @amount += 1
1 2
23
3
23
4
24
Connascence of Timing
@amount += 1 @amount += 1
1 2
23
3
23
4
24
Reordering Steps
@amount += 1 @amount += 1
1 3
24
2
25
4
25
Mutual Exclusion
@amount += 1
Do These Together 1 3
@amount += 1
24
2
25
4
25
Connascence of Timing
@amount += 1
Do These Together 1 3
@amount += 1
24
2
25
4
25
Connascence of Timing
@amount += 1
Do These Together 1 3
@amount += 1
24
2
25
4
25
Summary
Connascence
Static Connascence of Name Connascence of Type Connascence of Meaning Connascence of Algorithm Connascence of Position
Dynamic Connascence of Execution Connascence of Timing Connascence of Value Connascence of Identity Contranascence
Rules
Rule of Locality Rule of Degree
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
Questions?
Thank You!
git://github.com/jimweirich/presentation_connascence.git
Copyright 2009 by Jim Weirich, Some Rights Reserved