SlideShare a Scribd company logo
Global
Design
Principles
The Quest for

Matthias Noback
Stability
Change
Stability versus change
• Backwards compatibility of APIs

• Semantic versioning

• HTTP status codes

• XML schemas
For internal APIs
only!
The quest for global design principles (SymfonyLive Berlin 2015)
The key is in the concept of
communication
ReceiverSender
What's being communicated?
Message
Type ("BookHotel")

Value (“Golden Tulip", “15-10-2015", “16-10-2015”)
Message flavours
Command Event
Imperative
"BookHotel"
Informational
"HotelWasBooked"
Message flavours
Query Document
Interrogatory
"GetRecentBookings"
Neutral
"BookingsCollection"
Sender
Construct the message
Message
Translate 

Construct

(Prepare for

transport)
Receiver
Deconstruct the message
(Unwrap)

Translate

Construct
Global design
principles can be
discovered
if we recognise the fact that
communication between objects and
applications are (more or less) equal
Communication between
objects
• Calling a function is like sending a message

• The function and its parameters are the message
type

• The arguments constitute the value of the message
class AccountService
{
public function deposit($accountId, Money $amount)
{
...
}
}
Opportunity for
sending a
message
Inter-object communication
$money = new Money(20000, 'EUR');
$userId = 123;
$accountService->deposit(
$userId,
$money
);
Translation
The sender prepares the message for the receiver
Prepare the
message
Send the message
Communication between
applications
• An HTTP request is a message

• The HTTP method and URI are the type of the
message

• The HTTP request body constitutes the value of the
message
Or AMQP, Stomp, Gearman, ...
PUT /accounts/deposit/ HTTP/1.1
Host: localhost
{
"accountId": "123",
"currency": "EUR",
"amount": 20000
}
Inter-application
communication
Opportunity for
sending a
message
$uri ='/accounts/deposit/';
$data = json_encode([
'accountId' => 123
'currency' => 'EUR',
'amount' => 20000
]);
$httpClient
->createRequest('PUT', $uri, $data)
->send();
Translation
Prepare the
message
Send the message
/** @Route("/accounts/deposit") */
function depositAction(Request $request)
{
$request = json_decode($request->getContent());
$money = new Money(
$request['amount'],
$request['currency']
);
$this->get('account_service')->deposit(
$request['accountId'],
$money
);
return new Response(null, 200);
}
Translation
Prepare the
message
Send the message
Global design
principles
Should be applicable to both inter-object and inter-application communication
Part I
Stability
III Implementation
II Information
Sender Receiver
Communication
Dependency
relation!
Stable Unstable
What is safer?
Unstable Stable
OR
To be stable
"Steady in position or balance;
firm"
Irresponsible
What makes something
unstable?
1. Nothing depends on it
It doesn't need to stay the same for
anyone
Dependent
What makes something
unstable?
2. It depends on many things
Any of the dependencies could change at
any time
Stability is not a
quality of one thing
It emerges from the environment
of that thing
Responsible
What makes something
stable?
1. Many things depend on it
It has to stay the same, because change would break dependents
Independent
What makes something
stable?
2. It depends on nothing
It is not affected by changes in
anything
–The Stable dependencies principle
Depend in the
direction of stability
Stable package
Unstable
package
What to do when this
happens?
Stable package
Depend on something
that you own
Unstable
package
Stable package
–The Dependency inversion principle
Always depend on abstractions,
not on concretions
Dependency inversion for
objects
• Depend on an interface instead of a class

• Separate a task from its implementation
Stable thing
Communication
between systems
External
application
(unstable)
Mediator
Stable thing
Slightly better
External
application
(unstable)
ConsumerApplication
Communication
between systems
Message
queue
External
application
(unstable)
Dependency inversion for
systems
• Depend on your own (messaging) system

• Communicate with other applications through a
message queue
Part II
Information
I Stability
III Implementation
Knowledge, data, duplication
Nameplate order
system
Nameplate
machine
Business automation for
creating nameplates
<h1>You are about to order a nameplate!</h1>
<p>Name on the plate: {{ name }}<br/>
Width of the plate: {{ 12*(name|length) }} cm.</p>
Calculating the width of a
nameplate
Knowledge
class Nameplate
{
private $name;
function __construct($name) {
$this->name = $name;
}
function widthInCm() {
return strlen($this->name) * 12;
}
}
Data object
Knowledge is close to
the subject
<h1>You are about to order a nameplate!</h1>
<p>Name on the plate: {{ nameplate.name }}<br/>
Width of the plate: {{ nameplate.widthInCm) }}
cm.</p>
No knowledge in the template
<nameplate>
<name>Ibuildings</name>
</nameplate>
Serialized Nameplate object
// calculate the width of the nameplate
$nameplate = deserialize($xml);
$name = $nameplate['name'];
$width = strlen($name);
$widthPerCharacterInCm = 12;
$widthInCm = $width * $widthPerCharacterInCm;
// configure the nameplate machine ;)
Accepting messages
Duplication of knowledge
<nameplate>
<name>Ibuildings</name>
<width>120</width>
</nameplate>
Deduplication
Knowledge is in one place,
facts can be everywhere
$nameplate = deserialize($xml);
$width = $nameplate['width'];
Accepting messages
No duplicate knowledge
anymore
–The Don't repeat yourself principle
“Every piece of knowledge must
have a single, unambiguous,
authoritative representation
within a system.”
Even across applications!
"Don't repeat yourself"
• Doesn't mean you can't repeat data

• It means you can't have knowledge in multiple
locations
Mutability
What's the difference
between...
class Money
{
private $amount;
private $currency;
public function setAmount($amount) {
$this->amount = $amount;
}
public function getAmount() {
return $this->amount;
}
...
}
... and this
class Money
{
public $amount;
public $currency;
}
Inconsistent data
$savings = new Money();
$savings->setAmount(1000);
// what's the currency at this point?
$savings->setCurrency('USD');
// only now do we have consistent data
$savings->setCurrency('EUR');
// we have a lot more money now!
$savings->setAmount('Amsterdam');
Making something better of this
class Money
{
private $amount;
private $currency;
public function __construct($amount, $currency) {
$this->setAmount($amount);
}
private function setAmount($amount) {
if (!is_int($amount) || $amount < 0) {
throw new InvalidArgumentException();
}
$this->amount = $amount;
}
}
Private
Required
Immutability
• Once created, can not be modified

• Can only be replaced
Consistent data!
$savings = new Money(1000, 'USD');
// we already have consistent data
// we can't change anything anymore
Immutable data!
Using immutable values
• Prevents bugs

• Prevents invalid state
What about API messages?
<money>
<amount>1000</amount>
<currency>USD</currency>
</money>
PUT /savings/
<money>
<currency>EUR</currency>
</money>
POST /savings/
Large object graphs
<user>
<first-name/>
<last-name/>
<mobile-phone-number/>
<email-address/>
<homepage/>
<orders>
<order/>
...
</orders>
<tickets>
<ticket/>
...
</tickets>
<payments>
<payment/>
...
</payments>
</user>
Forms & Doctrine ORM
$form = $this->createForm(new MoneyType());
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($form->getData());
// calculates change set and executes queries
$em->flush();
}
If you allow your users to
change every field at any time
• You end up with inconsistent data

• You loose the why of a change

• You end up with the what of only the last change

• You ignore the underlying real-world scenario
The quest for global design principles (SymfonyLive Berlin 2015)
Commands and events
Register ConfirmRegistration
SendMessage
RegistrationConfirmed
MessageSent
UserRegistered
Application
Tomorrow!
True
• Messages should serve actual use cases instead
of patch operations

• After processing them, data should be in a valid
state
Part III
Implementation
I Stability
II Information
IV Conclusion
Implementation
Leaking implementation
details
class Person
{
/**
* @return PhoneNumber[]
*/
public function getPhoneNumbers() {
return $this->phoneNumbers;
}
}
Initial implementation
class Person
{
/**
* @return ArrayCollection
*/
public function getPhoneNumbers() {
return $this->phoneNumbers;
}
}
Implementation leakage
(Doctrine)
class Person
{
/**
* @return PhoneNumber[]
*/
public function getPhoneNumbers() {
return $this->phoneNumbers->toArray();
}
}
Hiding implementation
class NameplateController
{
function getAction($id) {
$nameplate = $this
->getDoctrine()
->getManager()
->getRepository(Nameplate::class)
->findOneBy(['id' => $id]);
if ($nameplate === null) {
throw new NotFoundHttpException();
}
...
}
}
More implementation hiding
Actual field names!
null or false?
"find"?
class NameplateRepository
{
function byId($id) {
$nameplate = $this
->findOneBy(['id' => $id]);
if ($nameplate === null) {
throw new NameplateNotFound($id);
}
return $nameplate;
}
}
Push it out of sight
Domain-specific exception
Hide specific return value
No "find"
class NameplateController
{
function getAction($id) {
try {
$nameplate = $this
->nameplateRepository
->byId($id);
} catch (NameplateNotFound $exception) {
throw new NotFoundHttpException();
}
...
}
}
Respect layers
Convert domain
exception to web
specific exception
Plain old OOP
• Encapsulation

• Abstraction
Limited by implementation
details
<ticket>
...
<priority type="integer">1</priority>
...
Assembla API
We do "switch ($priority)"
<ticket>
...
<priority key="highest">
<label>Highest</label>
</priority>
...
Why not...
<ticket>
...
<is-story type="boolean">false</is-story>
<total-estimate type="float">0.0</total-estimate>
...
Assembla API
Table "tickets" has a column
"is_story"
<story>
...
<total-estimate type="float">0.0</total-estimate>
...
Why not...
Design your messages in such
a way that
• You hide your implementation

• Clients won't need to reimplement your application

• Clients get the information they need
API discovery
/**
* @param string $password
* @param integer $algo
* @param array $options
*/
function password_hash($password, $algo, array $options = array());
Undiscoverable API
What are my options here?
And here?
class Algorithm extends SplEnum
{
const __default = self::BCRYPT;
const BCRYPT = 1;
}
Allow no mistakes
[
'salt' => '...'
'cost' => 10
]
Options for bcrypt hashing
class Bcrypt implements HashingStrategy
{
/**
* @param integer $cost
* @param string|null $salt
*/
public function __construct($cost, $salt = null) {
...
}
}
Inject a strategy
function password_hash(
$password,
HashingStrategy $hashingStrategy
);
Inject a strategy
More explicit and...
discoverable!
Discoverability of an API
• Full Reflection capabilities :)

• Basic knowledge of English
// I've got this password I want to hash…
$password = ...;
// Look, I found a function for this: password_hash()
password_hash($password, HashingStrategy $hashingStrategy);
// It requires an argument: a password (string)
// I already got a password right here:
password_hash($password);
// Wait, it requires a hashing strategy (a HashingStrategy object)
// I just found a class implementing that interface:
$hashingStrategy = new BcryptStrategy();
// That doesn't work, BcryptStrategy needs a cost
$hashingStrategy = new BcryptStrategy(10);
password_hash($password, $hashingStrategy);
Example of API discovery
Who is talking?
How stupid are they?
How do you find out a valid range?
/**
* @param array $options
*/
function some_function(array $options);
/**
* @param integer $type
*/
function some_other_function($type);
/**
* @param object $command
*/
function handle($command);
Undiscoverable APIs
Any kind of API should be
maximally discoverable
Everything should be an object
A class is a type
Define lots of interfaces
An interface defines the
public API of functions
<?xml version="1.0" encoding="UTF-8"?>
<ticket>
<reporter>
<id>43</id>
<link rel="self" href="/api/reporters/43" />
<link rel="index" href="/api/reporters/" />
</reporter>
...
HATEOAS
Links are a way to explain an "object"
Summary/Hypothesis
• Objects are just like applications

• Try to apply the same rules to them
Think about
• Stable dependencies

• Duplication of facts, not knowledge

• Immutability over mutability

• No leakage of implementation details

• Everything should be maximally discoverable
Questions? Feedback?
joind.in/15060 Thanks!

More Related Content

PDF
Symfony & Javascript. Combining the best of two worlds
PDF
Guard Authentication: Powerful, Beautiful Security
PDF
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
PDF
The quest for global design principles - PHP Benelux 2016
PDF
Symfony2 revealed
PDF
Who killed object oriented design?
PDF
Symfony: Your Next Microframework (SymfonyCon 2015)
PDF
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Symfony & Javascript. Combining the best of two worlds
Guard Authentication: Powerful, Beautiful Security
Symfony Guard Authentication: Fun with API Token, Social Login, JWT and more
The quest for global design principles - PHP Benelux 2016
Symfony2 revealed
Who killed object oriented design?
Symfony: Your Next Microframework (SymfonyCon 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)

What's hot (20)

PDF
Matters of State
PPTX
Hacking hhvm
PDF
How Kris Writes Symfony Apps
PDF
Laravel 5.2 Gates, AuthServiceProvider and Policies
PDF
Symfony tips and tricks
PDF
Building a Pyramid: Symfony Testing Strategies
PDF
Osiąganie mądrej architektury z Symfony2
PDF
Symfony tips and tricks
PDF
JavaScript Promises
PDF
Twig tips and tricks
PDF
Promise pattern
PPTX
JavaScript Promises
PDF
Symfony 2
PDF
Keeping the frontend under control with Symfony and Webpack
PDF
$q and Promises in AngularJS
PPTX
Maintainable JavaScript 2012
PDF
Frontin like-a-backer
PPTX
5 Tips for Better JavaScript
PDF
Advanced Interfaces and Repositories in Laravel
KEY
Overlays, Accordions & Tabs, Oh My
Matters of State
Hacking hhvm
How Kris Writes Symfony Apps
Laravel 5.2 Gates, AuthServiceProvider and Policies
Symfony tips and tricks
Building a Pyramid: Symfony Testing Strategies
Osiąganie mądrej architektury z Symfony2
Symfony tips and tricks
JavaScript Promises
Twig tips and tricks
Promise pattern
JavaScript Promises
Symfony 2
Keeping the frontend under control with Symfony and Webpack
$q and Promises in AngularJS
Maintainable JavaScript 2012
Frontin like-a-backer
5 Tips for Better JavaScript
Advanced Interfaces and Repositories in Laravel
Overlays, Accordions & Tabs, Oh My
Ad

Viewers also liked (20)

PDF
Techniques d'accélération des pages web
PDF
Get Soaked - An In Depth Look At PHP Streams
PDF
Diving deep into twig
ODP
Elastic Searching With PHP
PDF
Automation using-phing
ODP
PHP5.5 is Here
PPTX
Electrify your code with PHP Generators
PDF
Mocking Demystified
PDF
Top tips my_sql_performance
PDF
Understanding Craftsmanship SwanseaCon2015
PDF
Why elasticsearch rocks!
PDF
Writing infinite scalability web applications with PHP and PostgreSQL
PDF
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
PDF
L'ABC du BDD (Behavior Driven Development)
PDF
Behat 3.0 meetup (March)
PDF
TDD with PhpSpec - Lone Star PHP 2016
PDF
Performance serveur et apache
PDF
Caching on the Edge
PDF
The Wonderful World of Symfony Components
PDF
PHPSpec - the only Design Tool you need - 4Developers
Techniques d'accélération des pages web
Get Soaked - An In Depth Look At PHP Streams
Diving deep into twig
Elastic Searching With PHP
Automation using-phing
PHP5.5 is Here
Electrify your code with PHP Generators
Mocking Demystified
Top tips my_sql_performance
Understanding Craftsmanship SwanseaCon2015
Why elasticsearch rocks!
Writing infinite scalability web applications with PHP and PostgreSQL
Si le tdd est mort alors pratiquons une autopsie mix-it 2015
L'ABC du BDD (Behavior Driven Development)
Behat 3.0 meetup (March)
TDD with PhpSpec - Lone Star PHP 2016
Performance serveur et apache
Caching on the Edge
The Wonderful World of Symfony Components
PHPSpec - the only Design Tool you need - 4Developers
Ad

Similar to The quest for global design principles (SymfonyLive Berlin 2015) (20)

PDF
Dutch PHP Conference 2015 - The quest for global design principles
PDF
The Quest for Global Design Principles
PDF
Object Oriented Programming for WordPress Plugin Development
PDF
PDF
Test Presentation
PDF
ODP
Introduction to Domain-Driven Design
PPTX
L06 Using Design Patterns
PDF
Effective PHP. Part 3
PDF
Why is crud a bad idea - focus on real scenarios
KEY
Drive your dba crazy in 3 easy steps
PDF
Object Oriented Programming in PHP
PDF
OOPs Concept
PDF
Designing your API Server for mobile apps
PDF
Beyond Design Principles and Patterns
ZIP
Object Oriented PHP5
PPTX
Implementing The Open/Closed Principle
PDF
Dependency Injection for PHP
PPT
Class 7 - PHP Object Oriented Programming
PPTX
Patterns, Paradigms, and Governance 2013-10-03
Dutch PHP Conference 2015 - The quest for global design principles
The Quest for Global Design Principles
Object Oriented Programming for WordPress Plugin Development
Test Presentation
Introduction to Domain-Driven Design
L06 Using Design Patterns
Effective PHP. Part 3
Why is crud a bad idea - focus on real scenarios
Drive your dba crazy in 3 easy steps
Object Oriented Programming in PHP
OOPs Concept
Designing your API Server for mobile apps
Beyond Design Principles and Patterns
Object Oriented PHP5
Implementing The Open/Closed Principle
Dependency Injection for PHP
Class 7 - PHP Object Oriented Programming
Patterns, Paradigms, and Governance 2013-10-03

More from Matthias Noback (20)

PDF
Rector fireside chat - PHPMiNDS meetup
PDF
Service abstractions - Part 1: Queries
PDF
Hexagonal Symfony - SymfonyCon Amsterdam 2019
PDF
Advanced web application architecture - PHP Barcelona
PDF
A testing strategy for hexagonal applications
PDF
Advanced web application architecture - Talk
PDF
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
PDF
Layers, ports and adapters
PDF
Beyond design principles and patterns (muCon 2019 edition)
PDF
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
PDF
Advanced web application architecture Way2Web
PDF
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
PDF
Building Autonomous Services
PDF
Advanced Application Architecture Symfony Live Berlin 2018
PDF
Designing for Autonomy
PDF
Docker workshop
PDF
Docker swarm workshop
PDF
Docker compose workshop
PDF
Building autonomous services
PDF
Designing for autonomy
Rector fireside chat - PHPMiNDS meetup
Service abstractions - Part 1: Queries
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Advanced web application architecture - PHP Barcelona
A testing strategy for hexagonal applications
Advanced web application architecture - Talk
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
Layers, ports and adapters
Beyond design principles and patterns (muCon 2019 edition)
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Advanced web application architecture Way2Web
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Building Autonomous Services
Advanced Application Architecture Symfony Live Berlin 2018
Designing for Autonomy
Docker workshop
Docker swarm workshop
Docker compose workshop
Building autonomous services
Designing for autonomy

Recently uploaded (20)

PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Nekopoi APK 2025 free lastest update
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
PDF
AI in Product Development-omnex systems
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PPTX
L1 - Introduction to python Backend.pptx
PPTX
Introduction to Artificial Intelligence
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
PTS Company Brochure 2025 (1).pdf.......
PDF
System and Network Administraation Chapter 3
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PDF
Adobe Illustrator 28.6 Crack My Vision of Vector Design
PDF
Design an Analysis of Algorithms I-SECS-1021-03
PDF
Understanding Forklifts - TECH EHS Solution
PDF
Odoo Companies in India – Driving Business Transformation.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Nekopoi APK 2025 free lastest update
How to Choose the Right IT Partner for Your Business in Malaysia
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Adobe Premiere Pro 2025 (v24.5.0.057) Crack free
AI in Product Development-omnex systems
Upgrade and Innovation Strategies for SAP ERP Customers
Navsoft: AI-Powered Business Solutions & Custom Software Development
Design an Analysis of Algorithms II-SECS-1021-03
L1 - Introduction to python Backend.pptx
Introduction to Artificial Intelligence
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
How Creative Agencies Leverage Project Management Software.pdf
PTS Company Brochure 2025 (1).pdf.......
System and Network Administraation Chapter 3
How to Migrate SBCGlobal Email to Yahoo Easily
Adobe Illustrator 28.6 Crack My Vision of Vector Design
Design an Analysis of Algorithms I-SECS-1021-03
Understanding Forklifts - TECH EHS Solution
Odoo Companies in India – Driving Business Transformation.pdf

The quest for global design principles (SymfonyLive Berlin 2015)