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
Avoiding the mud - Symfony Live London
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Richard Miller
September 21, 2013
Technology
790
7
Share
Avoiding the mud - Symfony Live London
Richard Miller
September 21, 2013
More Decks by Richard Miller
See All by Richard Miller
Introduction to Symfony2 - DrupalCamp London 2014
richardmiller
0
310
Avoiding the mud
richardmiller
22
11k
better searching with elasticsearch - PHPConfPL
richardmiller
2
530
better searching with elasticsearch
richardmiller
2
310
What do I get from the full stack framework?
richardmiller
1
1.6k
Advanced Service Container Utilization
richardmiller
4
1.2k
Dependency Injection and the Symfony2 Service Container
richardmiller
9
13k
Other Decks in Technology
See All in Technology
すごいぞManaged Kubernetes
harukasakihara
1
320
TanStack Start エコシステムの現在地 / TanStack Start Ecosystem 2026
iktakahiro
1
290
Oracle Cloud Infrastructure(OCI):Onboarding Session(はじめてのOCI/Oracle Supportご利⽤ガイド)
oracle4engineer
PRO
2
17k
AIドリブン開発の実践知 ― AI-DLC Unicorn Gym実施から見えた可能性と課題
mixi_engineers
PRO
0
110
サイボウズ 開発本部採用ピッチ / Cybozu Engineer Recruit
cybozuinsideout
PRO
10
77k
Datadog で実現するセキュリティ対策 ~オブザーバビリティとセキュリティを 一緒にやると何がいいのか~
a2ush
0
190
GitHub Actions侵害 — 相次ぐ事例を振り返り、次なる脅威に備える
flatt_security
13
7.5k
第26回FA設備技術勉強会 - Claude/Claude_codeでデータ分析 -
happysamurai294
0
380
Data Enabling Team立ち上げました
sansantech
PRO
0
270
OCI技術資料 : ロード・バランサ 概要 - FLB・NLB共通
ocise
4
27k
I ran an automated simulation of fake news spread using OpenClaw.
zzzzico
1
910
15年メンテしてきたdotfilesから開発トレンドを振り返る 2011 - 2026
giginet
PRO
2
280
Featured
See All Featured
Between Models and Reality
mayunak
3
260
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
93
SEO in 2025: How to Prepare for the Future of Search
ipullrank
3
3.4k
Fashionably flexible responsive web design (full day workshop)
malarkey
408
66k
Conquering PDFs: document understanding beyond plain text
inesmontani
PRO
4
2.6k
Darren the Foodie - Storyboard
khoart
PRO
3
3.1k
For a Future-Friendly Web
brad_frost
183
10k
HDC tutorial
michielstock
1
600
Building a Modern Day E-commerce SEO Strategy
aleyda
45
9k
Producing Creativity
orderedlist
PRO
348
40k
The Curse of the Amulet
leimatthew05
1
11k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
100
Transcript
AVOIDING THE MUD by Richard Miller http://www.flickr.com/photos/burge5000/22568539/
@mr_r_miller http://www.richardmiller.co.uk
http://www.flickr.com/photos/brostad/8583990904
http://www.flickr.com/photos/dominik99/384027019
http://www.flickr.com/photos/jasmeet/2158002974
Bundles For Everything? http://www.flickr.com/photos/jarkel/2288176
Separate Domain Model From Bundles http://www.flickr.com/photos/30666161@N05/3705814710
HumanResourcesBundle
HumanResourcesBundle HumanResources
HumanResourcesBundle HumanResources
http://www.flickr.com/photos/26582481@N08/3040936355 Enough?
Still Tightly Coupled
AbsenceEntity Request Absence Form Cancel Absence Form Approve Absence Form
Change Absence Type Form
Sensio\HumanResources\Absence\AbsenceEntity: properties: reason: - NotBlank: { groups: [cancellation] } -
Length: { max: 300, groups: [cancellation] }
AbsenceEntity Request Absence Form Cancel Absence Form Approve Absence Form
Change Absence Type Form Request Absence Command Cancel Absence Command Approve Absence Command Change Absence Type Command
What About Templates?
AbsenceEntity upcoming .html .twig details .html .twig calendar .html .twig
unapproved .html .twig
{% if absence.endDate < date() %} past {% else %}
absence.status {% endif %} getDisplayStatus() AbsenceEntity getEndDate() getStatus()
{% if absence.endDate < date() %} past {% else %}
absence.status {% endif %} getDisplayStatus() AbsenceEntity getEndDate() getStatus()
{{ absence.displayStatus }} getDisplayStatus() AbsenceEntity getEndDate() getStatus() getDisplayStatus()
{{ absence.displayStatus }} getDisplayStatus() AbsenceEntity getEndDate() getStatus() getDisplayStatus()
AbsenceEntity Request Absence Form Cancel Absence Form Approve Absence Form
Change Absence Type Form Absence View upcoming .html .twig details .html .twig calendar .html .twig unapproved .html .twig
AbsenceEntity Request Absence Form Cancel Absence Form Approve Absence Form
Change Absence Type Form Absence View upcoming .html .twig details .html .twig calendar .html .twig unapproved .html .twig getStatus()
Unapproved Absence View Calendar View AbsenceEntity Request Absence Form Cancel
Absence Form Approve Absence Form Change Absence Type Form Upcoming Absences View Absence Details View upcoming .html .twig details .html .twig calendar .html .twig unapproved .html .twig
SRP
Behaviour Not State
Request Absence Controller Absence Entity setReason($reason) setStatus(AbsenceEntity::CANCELLED) setCancellationDate(new DateTime()) Cancel
Absence Command getReason()
Request Absence Controller Absence Entity cancel($reason) Cancel Absence Command getReason()
Cancel Absence Command Absence Entity Validate internal consistency Validate user
input
CancelAbsenceComm andHandler Cancel Absence Command Handler AbsenceEntity cancel($reason) handle($command) Request
Absence Controller Absence Entity cancel($reason) Cancel Absence Command
Infrastructure?
Absence Repository (Interface) findById($id) findUpcomingByMember($member) findAllByMember($member) Doctrine ORM Absence Repository
Doctrine ODM Absence Repository Guzzle Client Absence Repository Infrastructure Domain
AbsenceEntity Absence Repository Domain Bundle Service Config Infrastructure Doctrine ORM
Absence Repository Mapping Config
Absence Repository (Interface) findById($id) findUpcomingByMember($member) findAllByMember($member) add(AbsenceEntity $absence)
Events
OnUpdate Event AbsenceEntity Dispatches
OnUpdate Event AbsenceEntity Dispatches
Absence Cancelled Event Cancel Absence Command Handler Dispatches
Absence Cancelled Event In Memory Listener Immediate Action Place In
Messaging Queue Listens
Absence Cancelled Event Flush Listener Listens Absence Approved Event Domain
Infrastructure Listens
Separating Commands From Queries
Command Command Handler Entity Datastore
Datastore View Datastore View Datastore Command Command Handler Entity Event
Datastore View Datastore View Datastore Command Command Handler Entity View
Template Event
Separating Bundles Horizontally
Non-application Specific Code
HumanResources CustomLoggingBundle HumanResourcesBundle
HumanResourcesBundle HumanResources CustomLoggingBundle CustomLogging CustomLoggingBundle CustomLoggingBundle CustomLogging HumanResourcesBundle
HumanResources CustomLoggingBundle CustomLogging CustomLoggingBundle CustomLoggingBundle CustomLogging If it must! HumanResourcesBundle
HumanResources CustomLoggingBundle CustomLogging CustomLoggingBundle CustomLoggingBundle CustomLogging HumanResourcesBundle
Separating By Context
AbsencePlannerBundle AbsencePlanner CustomLoggingBundle CustomLogging CustomLoggingBundle RecruitmentBundle Recruitment
Message Queue/REST AbsencePlannerBundle AbsencePlanner CustomLoggingBundle CustomLogging CustomLoggingBundle RecruitmentBundle Recruitment
CustomLoggingBundle CustomLogging CustomLoggingBundle RecruitmentBundle Recruitment Off the shelf Package Message
Queue/REST Message Queue/REST AbsencePlannerBundle AbsencePlanner
Separate Commonality
AbsencePlannerBundle AbsencePlanner RecruitmentBundle Recruitment AbsencePlannerBundle AbsencePlanner CustomLoggingBundle CustomLogging CustomLoggingBundle RecruitmentBundle
Recruitment User Management
!= Staff Member Entity User Entity
AbsencePlannerBundle AbsencePlanner AbsencePlannerBundle AbsencePlanner CustomLoggingBundle CustomLogging CustomLoggingBundle RecruitmentBundle Recruitment UserManagementBundle
Now?
http://www.flickr.com/photos/mtsofan/8313606885
https://github.com/beberlei/litecqrs-php http://behat.org/
http://williamdurand.fr/ http://verraes.net/#blog http://www.whitewashing.de/
QUESTIONS?