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
Architecting is Difficult: London Web March 2014
Search
Jack Franklin
March 20, 2014
Technology
3
300
Architecting is Difficult: London Web March 2014
Jack Franklin
March 20, 2014
Tweet
Share
More Decks by Jack Franklin
See All by Jack Franklin
Advanced React Meetup: Testing JavaScript
jackfranklin
1
250
Components on the Web: Frontend NE
jackfranklin
1
830
ReactiveConf: Lessons Migrating Complex Software
jackfranklin
0
500
Front Trends: Migrating complex software
jackfranklin
1
830
Migrating from Angular to React: Manc React
jackfranklin
1
200
Half Stack Fest: Webpack
jackfranklin
4
570
FullStackFest: Elm for JS Developers
jackfranklin
1
260
Codelicious: Intro to ES2015
jackfranklin
0
400
PolyConf: Elm for JS Developers
jackfranklin
0
290
Other Decks in Technology
See All in Technology
白金鉱業Meetup_Vol.22_Orbital Senseを支える衛星画像のマルチモーダルエンベディングと地理空間のあいまい検索技術
brainpadpr
2
290
Oracle Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
4
1.2k
モブプログラミング再入門 ー 基本から見直す、AI時代のチーム開発の選択肢 ー / A Re-introduction of Mob Programming
takaking22
5
1.3k
Claude Codeの進化と各機能の活かし方
oikon48
21
12k
マルチロールEMが実践する「組織のレジリエンス」を高めるための組織構造と人材配置戦略
coconala_engineer
3
710
Kaggleの経験が実務にどう活きているか / kaggle_findy
sansan_randd
7
1.4k
Ultra Ethernet (UEC) v1.0 仕様概説
markunet
3
250
Oracle Database@Google Cloud:サービス概要のご紹介
oracle4engineer
PRO
5
1.2k
20260311 技術SWG活動報告(デジタルアイデンティティ人材育成推進WG Ph2 活動報告会)
oidfj
0
290
[JAWS DAYS 2026]私の AWS DevOps Agent 推しポイント
furuton
0
140
Security Diaries of an Open Source IAM
ahus1
0
210
[2026-03-07]あの日諦めたスクラムの答えを僕達はまだ探している。〜守ることと、諦めることと、それでも前に進むチームの話〜
tosite
0
170
Featured
See All Featured
How to optimise 3,500 product descriptions for ecommerce in one day using ChatGPT
katarinadahlin
PRO
1
3.5k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
310
職位にかかわらず全員がリーダーシップを発揮するチーム作り / Building a team where everyone can demonstrate leadership regardless of position
madoxten
61
52k
What does AI have to do with Human Rights?
axbom
PRO
1
2k
BBQ
matthewcrist
89
10k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Designing Experiences People Love
moore
143
24k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
120
The SEO Collaboration Effect
kristinabergwall1
0
390
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
69
Test your architecture with Archunit
thirion
1
2.2k
Transcript
Architecting is Difficult @Jack_Franklin
Any fool can write code that a computer can understand.
Good programmers write code that humans can understand. ! Martin Fowler [@martinfowler]
What makes code difficult to work with?
YMMV
you’re never going to get it perfect first time
Defer concrete decisions as late as possible - you'll never
again know less about the problem than you do right now and the correct abstraction will become clearer over time. ! Andy Appleton [@appltn]
writing good code improving existing code
Writing Good Code: Tests
drive your API design
difficult to test == difficult to use
confidence when refactoring (but we’ll come back to this later)
Writing Good Code: Naming Conventions
There are only two hard things in Computer Science: cache
invalidation and naming things. ! Phil Karlton
There are only two hard things in Computer Science: cache
invalidation, naming things and off by one errors. ! ???
prefer verbosity
be consistent use the same nouns and verbs
Writing Good Code: Coding Standards
editorconfig.org
actual standard is irrelevant pick one and stick to it
Writing Good Code: Single Responsibility
do one thing and do it well
Not one thing well class EmailSender def initialize(csv) ! def
parse_csv_for_emails ! def send_email end
Better class EmailSender def initialize(csv) def parse_csv_for_emails Parser.new(csv).emails def send_email
end ! class Parser def initialize(csv) def emails end
Writing Good Code: Decoupled Components
class EmailSender def initialize(csv) def parse_csv_for_emails Parser.new(csv).emails def send_email end
! class Parser def initialize(csv) def emails end This knowledge isn’t needed here
class EmailSender def initialize(emails) def send_email end ! class Parser
def initialize(csv) def emails end ! emails = Parser.new(csv).emails EmailSender.new(emails).send_email knows how to send an email to an array of emails knows how to parse a CSV and get the email addresses
Writing Good Code: Separate Aggressively
don’t be afraid to create classes / objects
easier to merge two tiny classes than split up one
massive one
Refactoring
None
Refactoring: alter code without changing behaviour
you have to have tests!
Code Smells
Code Smell: some code which may indicate a problem
You don’t fix code smells. You look at them and
see if they indicate a problem you can fix. ! Joe Ferris [@joe_ferris]
class SomeMapThing def initialize(x, y) end ! class LatLong def
self.get_lat_long(x, y) end ! class User def coords [x, y] end
data clumps continually passing round two objects as arguments
class SomeMapThing def initialize(coords) ! class LatLong def self.get_lat_long(coords) !
class User def coords ! class Coords def x def y ! coords = Coords.new(2, 3) LatLong.get_lat_long(coords)
if two arguments are tightly related, encapsulate that knowledge
class GraphDrawer def draw width = 165 + bar_width height
= 170.2 + bar_height … end
why 165? why 170.2? This is very common in JavaScript
/ jQuery code, and CSS too.
class GraphDrawer GRAPH_HEIGHT_PADDING = 170.2 GRAPH_WIDTH_PADDING = 165 def draw
width = GRAPH_WIDTH_PADDING * bar_width height=GRAPH_HEIGHT_PADDING + bar_height end
no knowledge should be left in your head
<% if user != nil %> <h2><%= user.welcome_message %></h2> <%
else %> <h2>Please sign in</h2> <% end %>
checking for nil / undefined
what does nil mean? no first name? system error? no
name yet? no user logged in?
implicit knowledge in a codebase is bad
class NullUser def welcome_message “Please sign in” end ! user
= current_user || NullUser.new <h2><%= user.welcome_message %></h2>
don’t check for nil
def check_for_overheating(system_monitor) if system_monitor.temperature > 100 system_monitor.sound_alarms end end
def check_for_overheating(system_monitor) if system_monitor.temperature > 100 system_monitor.sound_alarms end end
tell, don’t ask http://robots.thoughtbot.com/tell-dont-ask
system_monitor.check_for_overheating ! class SystemMonitor def check_for_overheating if temperature > 100
sound_alarms end end end
we’re now telling the object what to do rather than
asking it if it can do it
coupling http://robots.thoughtbot.com/types-of-coupling
def save(should_run_validations=true) if should_run_validations validate store else store ! #
in our app, everywhere user.save post.save(false)
control coupling
if I update the save method every usage of the
method has to change
(this actually happened in Rails)
better solution would be to split the methods up
you have to have some coupling, else nothing could talk
to anything
“If I change this method, how many changes do I
have to make else where?”
Publish and Subscribe
class ModuleA def init(b) def a_thing do_a_thing b.do_thing ! !
class ModuleB def do_thing # has to happen after ModuleA#a_thing
Module A knows too much
class ModuleA def init(event) def a_thing do_a_thing event.publish(‘a_thing_complete’) ! !
class ModuleB def init(event) event.subscribe(‘a_thing_complete’) { do_thing } ModuleA doesn’t know (or care) what modules listen to a_thing_complete
Now no module knows about the other
class ModuleA def init(event) def a_thing do_a_thing event.publish(‘a_thing_complete’) ! class
ModuleB … class ModuleC def init(event) event.subscribe(‘a_thing_complete’) { do_thing }
class User def posts_by_user blog.posts.where(user_id: id) end
The Law of Demeter
It’s an actual law!
A method of an object should only invoke only the
methods of the following kinds of objects: ! 1. itself 2. its parameters 3. any objects it creates 4. its direct component objects
class User def posts_by_user blog.posts.where(user_id: id) end multiple dots
class User def posts_by_user blog.posts_by_user(id) end ! class Blog def
posts_by_user(id) posts.where(user_id: id) end
avoid duplication of knowledge across your system
OK, so it’s not an actual law
Approaches to maintaining code
Every time you work with some code, leave it a
tiny bit better than when you left it
don’t ignore a problem or leave #FIXME comments
#todo: this entire class is screwed, fix it
if you need to make the change, but the change
is difficult
first refactor to make the change easy then make the
change!
you can’t get it right first time every time
keep friction to running tests low
because then you’ll run them
code reviews
http://robots.thoughtbot.com/ ! https://speakerdeck.com/jackfranklin ! http://refactoring.com/
Thanks! javascriptplayground.com @Jack_Franklin