Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Surrender The Illusion of Control
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Steve Tooke
September 07, 2015
Programming
310
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Surrender The Illusion of Control
SwanseaCon 2015
Steve Tooke
September 07, 2015
More Decks by Steve Tooke
See All by Steve Tooke
Ten reasons that BDD won’t save your development process
tooky
0
550
Quality at Startup Speed
tooky
1
140
Let me tell you a Story – CukeUp! AU 2016
tooky
0
60
Intro to BDD – CukeUp! AU 2016
tooky
0
55
Extreme Startup: Socrates UK 2014
tooky
1
150
Other Decks in Programming
See All in Programming
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
act1-costs.pdf
sumedhbala
0
110
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
0
280
はてなアカウント基盤 State of the Union
cockscomb
0
700
Lessons from Spec-Driven Development
simas
PRO
0
220
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
270
「AIで開発し、AIを届ける」をEvalでつなぐ 〜AIネイティブに始めるプロダクト開発の実践〜 / Connecting "Develop with AI, deliver AI" with Eval
rkaga
4
5.4k
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
200
Claspは野良GASの夢をみるか
takter00
0
210
Vite+ Unified Toolchain for the Web
naokihaba
0
340
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
940
The NotImplementedError Problem in Ruby
koic
1
930
Featured
See All Featured
AI Search: Implications for SEO and How to Move Forward - #ShenzhenSEOConference
aleyda
1
1.3k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
400
The Curse of the Amulet
leimatthew05
2
13k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
Statistics for Hackers
jakevdp
799
230k
Java REST API Framework Comparison - PWX 2021
mraible
34
9.4k
AI Search: Where Are We & What Can We Do About It?
aleyda
0
7.6k
The Illustrated Children's Guide to Kubernetes
chrisshort
51
52k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
250
Keith and Marios Guide to Fast Websites
keithpitt
413
23k
Transcript
Surrender The Illusion of Control @tooky – SwanseaConf 2015
Let It Go @tooky – SwanseaConf 2015
Caveat
What is good design?
Why is good design important?
None
None
None
None
None
Reduce the Cost of Change
None
XP
TDD
JUnit
4 Rules of Simple Design
None
None
None
None
None
Your code is your understanding of the problem you're exploring.
So it's only when you have your code in your
head that you really understand the problem. 1 Paul Graham
None
Connascence
None
None
Connascence1 1. The birth of two or more things at
the same time. 2. The act of growing together 1 From wiktionary
two components are connascent if a change in one would
require the other to be modified in order to maintain the overall correctness of the system
Static Connascence 1. Connascence of Name 2. Connascence of Type
3. Connascence of Meaning 4. Connascence of Algorithm 5. Connascence of Position
Dynamic Connascence 6. Connascence of Execution 7. Connascence of Timing
8. Connascence of Value 9. Connascence of Identity
Connascence of Name
Connascence of Name class CardTest < Minitest::Test def test_high_card_beats_low_card high_card
= Card.new("10", "♥") low_card = Card.new("2", "♣") assert high_card.beats?(low_card) end end class Card < Struct.new(:rank, :suit) def beats?(other_card) true end end
Connascence of Type
Connascence of Type public class DiamondTest { @Test public void
first_row_of_A_diamond() { String diamond = Diamond.upTo("A"); assertThat(diamond, is("A")); } @Test public void first_row_of_B_diamond() { String diamond = Diamond.upTo("B"); assertThat(diamond, is("-A-")); } @Test public void first_row_of_C_diamond() { String diamond = Diamond.upTo("C"); assertThat(diamond, is("--A--")); } }
Connascence of Type public class Diamond { public static String
upTo(String letter) { if ("C".equals(letter)) { return "--" + "A" + "--"; } if ("B".equals(letter)) { return "-" + "A" + "-"; } return "A"; } }
public class DiamondTest { @Test public void first_row_of_A_diamond() { String
diamond = Diamond.upTo("A"); assertThat(diamond, is("A")); } // ... } public class Diamond { public static String upTo(String letter) { if ("C".equals(letter)) { return "--" + "A" + "--"; } if ("B".equals(letter)) { return "-" + "A" + "-"; } return "A"; } }
Connascence of Type public class DiamondTest { @Test public void
first_row_of_A_diamond() { String diamond = Diamond.upTo('A'); assertThat(diamond, is("A")); } @Test public void first_row_of_B_diamond() { String diamond = Diamond.upTo('B'); assertThat(diamond, is("-A-")); } @Test public void first_row_of_C_diamond() { String diamond = Diamond.upTo('C'); assertThat(diamond, is("--A--")); } }
Connascence of Type public class Diamond { public static String
upTo(char letter) { if ('C'.equals(letter)) { return "--" + "A" + "--"; } if ('B'.equals(letter)) { return "-" + "A" + "-"; } return "A"; } }
Connascence of Meaning
Connascence of Meaning public class Diamond { public static String
upTo(char letter) { if ('C'.equals(letter)) { return "--" + "A" + "--"; } if ('B'.equals(letter)) { return "-" + "A" + "-"; } return "A"; } }
Connascence of Name > Connascence of Meaning public class Diamond
{ public static final char START_LETTER = 'A'; public static String upTo(char letter) { if ('C'.equals(letter)) { return "--" + START_LETTER + "--"; } if ('B'.equals(letter)) { return "-" + START_LETTER + "-"; } return valueof(START_LETTER); } }
Connascence of Algorithm
Connascence of Algorithm public class Diamond { public static final
char START_LETTER = 'A'; public static String upTo(char letter) { if ('C'.equals(letter)) { return "--" + START_LETTER + "--"; } if ('B'.equals(letter)) { return "-" + START_LETTER + "-"; } return valueof(START_LETTER); } }
Connascence of Algorithm public class Diamond { public static final
char START_LETTER = 'A'; public static String upTo(char letter) { if ('C'.equals(letter)) { return "--" + START_LETTER + "--"; } if ('B'.equals(letter)) { return "-" + START_LETTER + "-"; } return "" + START_LETTER + ""; } }
Connascence of Name > Connascence of Algorithm public class Diamond
{ public static final char START_LETTER = 'A'; public static String upTo(char letter) { return padding(letter) + START_LETTER + padding(letter); } private static string padding(char letter) { int paddingSize = letter - START_LETTER; return StringUtils.repeat("-", paddingSize); } }
Connascence of Position
Connascence of Position class CardTest < Minitest::Test def test_high_card_beats_low_card high_card
= Card.new("10", "♥") low_card = Card.new("2", "♣") assert high_card.beats?(low_card) end end class Card < Struct.new(:rank, :suit) end
Connascence of Position class CardTest < Minitest::Test def test_high_card_beats_low_card high_card
= Card.new("10", "♥") low_card = Card.new("2", "♣") assert high_card.beats?(low_card) end end class Card < Struct.new(:suit, :rank) end
Connascence of Position class CardTest < Minitest::Test def test_high_card_beats_low_card high_card
= Card.new("♥", "10") low_card = Card.new("♣", "2") assert high_card.beats?(low_card) end end class Card < Struct.new(:suit, :rank) end
Connascence of Name > Position class Card def initialize(rank:, suit:)
@rank = rank @suit = suit end # ... end
Connascence of Name > Position class CardTest < Minitest::Test def
test_high_card_beats_low_card high_card = Card.new(rank: "10", suit: "♥") low_card = Card.new(suit: "♣", rank: "2") assert high_card.beats?(low_card) end end
Locality
None
None
Locality class AvailableJobs def jobs [[customer, description]] end def assign_to(worker)
jobs.each do |customer, description| # ... end end end
Locality class AvailableJobs def jobs [[description, customer]] end def assign_to(worker)
jobs.each do |customer, description| # ... end end end
Locality class CompletedJobs def jobs [[customer, description]] end end
Locality class InvoiceClerk def generate_job_invoices(jobs) jobs.each do |customer, description| #
... end end end
Degree
Degree class CompletedJobs def jobs [[customer, reference, description, start_time, finish_time,
rate]] end end
Degree class InvoiceClerk def generate_job_invoices(jobs) jobs.each do |customer, reference, description,
start_time, finish_time, rate| # ... end end end
Degree class CompletedJob attr_reader :customer, :reference, :description, :start_time, :finish_time, :rate
end
Degree class CompletedJobs def jobs [job] end end
Degree class InvoiceClerk def generate_job_invoices(jobs) jobs.each do |job| # ...
end end end
Rules
The further apart two components are use weaker forms of
connascence
When you have a high degree of connascence convert to
a weaker form of connascence
Good Design?
Connascence
Red, Green... what now?2 2 http://silkandspinach.net/2015/05/20/red-green-what-now/
Principles
SOLID
DRY
Law of Demeter
Principles
None
Questions
http://tooky.co.uk
[email protected]
@tooky
Photos good_design_1.jpg: https://www.flickr.com/photos/opalsson/ bad_design.jpg: https://www.reddit.com/r/todayilearned/comments/2dvvja/til_that_in_order_to_preserve_the_states_natural/ greenfield.jpg: https://www.flickr.com/photos/ks_marks/ stuckInTheMud.jpg: https://www.flickr.com/photos/puuikibeach/ unicorn.jpg:
https://www.flickr.com/photos/wayfinder/ jimWeirich.jpg: https://www.flickr.com/photos/fraserspeirs/ celebrate.jpg: https://www.flickr.com/photos/clement127/ modular.jpg: https://www.flickr.com/photos/rahul3/ connected.jpg: https://www.flickr.com/photos/bernd_thaller/ reduceCost.jpg: https://www.flickr.com/photos/68751915@N05/ change.jpg: https://www.flickr.com/photos/petereed/