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
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
Oxcを導入して開発体験が向上した話
yug1224
4
340
[2026年度第1回ORセミナー] 計画最適化ベンチャーと競技プログラミング人材
terryu16
0
280
正しくソフトウェアを作る、前提を疑うための認知の視点 / doubt-premise
minodriven
21
7.1k
JavaDoc 再入門
nagise
1
420
The NotImplementedError Problem in Ruby
koic
1
960
「なぜそう決めたのか」を残し続ける仕組み ― Notion AI カスタムエージェント × Slack連携による設計判断の自動記録 - NIKKEI Tech Talk #47
niftycorp
PRO
0
230
Hatena Engineer Seminar #37「言語モデルの活用に関する研究」
slashnephy
0
230
気づいたらRubyで100作品 ー クリエイティブコーディングが生活の一部になるまで / 100 Ruby Sketches Later: How Creative Coding Became Part of My Life
chobishiba
3
610
Vue × Nuxt × Oxc どこまで使える?実運用の現在地
andpad
0
310
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.5k
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
0
160
さぁV100、メモリをお食べ・・・
nilpe
0
160
Featured
See All Featured
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
330
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.5k
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
580
The untapped power of vector embeddings
frankvandijk
2
1.8k
GraphQLとの向き合い方2022年版
quramy
50
15k
Thoughts on Productivity
jonyablonski
76
5.2k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
400
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
220
Color Theory Basics | Prateek | Gurzu
gurzu
0
370
Mind Mapping
helmedeiros
PRO
1
260
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
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/