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
560
Quality at Startup Speed
tooky
1
140
Let me tell you a Story – CukeUp! AU 2016
tooky
0
61
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
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
550
SREの積み重ねがAI駆動開発のガードレールになった ― 7つの実践/SRE Guardrails The 7
tomoyakitaura
8
5.6k
型も通る、synthも通る、それでも危ない 〜AIのCDKの権限とコストを機械で検証する〜 / It Passes Type Checks, It Passes Synth Checks, but It’s Still Risky — Automatically Verifying Permissions and Costs in AI’s CDK —
seike460
PRO
1
450
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
7k
音楽のための関数型プログラミング言語mimiumにおける多段階計算の活用
tomoyanonymous
1
360
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
180
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.8k
【やさしく解説 設計編・中級 #4】ルールの寿命と、システムの年輪
panda728
PRO
2
170
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.6k
任せる範囲はこう広がった / How the Scope of AI Delegation Has Expanded
nrslib
1
280
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
200
Built Our Own Background Agent at LayerX #aidevex_findy
layerx
PRO
9
3.5k
Featured
See All Featured
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
320
Color Theory Basics | Prateek | Gurzu
gurzu
0
400
Product Roadmaps are Hard
iamctodd
55
12k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.5k
How to build a perfect <img>
jonoalderson
1
5.8k
Music & Morning Musume
bryan
47
7.3k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
190
Amusing Abliteration
ianozsvald
1
240
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.7k
Are puppies a ranking factor?
jonoalderson
1
3.7k
Building the Perfect Custom Keyboard
takai
2
820
ラッコキーワード サービス紹介資料
rakko
1
4.1M
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/