SlideShare a Scribd company logo
Why Is CRUD a Bad Idea
Focus on Real Scenarios
Petr Heinz
More than 8 years of programming experience.
Loves clean code, regular expressions and
clever design.
Dedicated last year to developing the Shopsys
Framework, open source e-commerce
framework made with passion on Symfony 3.
✉ petr.heinz@shopsys.com
Typical CRUD
Create, Read, Update and Delete
Four basic functions of an persistent storage, often used as an API.
Can be mapped to SQL statements:
INSERT SELECT UPDATE DELETE
Can be mapped to HTTP methods (used in REST APIs):
PUT GET POST DELETE
Example: Article
class Article {
private $author, $text, $state, $published;
public function setAuthor(Author $author) {
$this->author = $author;
}
public function getAuthor() {
return $this->author;
}
public function setText($text) {
$this->text = $text;
}
// ...
}
class ArticleController {
public function create(...) {
// ...
}
public function update(...) {
// ...
$article->setAuthor($author);
$article->setText($text);
$article->setState($state);
$article->setPublished($published);
}
public function delete(...) {
// ...
}
}
Entities Must Follow Business Rules
Entities are often constrained by business rules and the consistency must be kept.
● Company customer must have VAT ID filled in his account.
● Sold out product must be hidden.
● Article in published state must have published date.
This is difficult to achieve in the previous example. That’s because all article
attributes can be changed independently. Developers are not restricted in the way
they interact with the object.
Example: Article without setters
class Article {
const STATE_UNPUBLISHED = 1;
const STATE_PUBLISHED = 2;
const STATE_DELETED = 3;
private $author, $text, $state, $published;
public function __construct(Author $author, $text, $state, DateTime $published = null) {
// ...
}
public function update(Author $author, $text, $state, DateTime $published = null) {
// ...
}
public function delete() {
$this->state = self::STATE_DELETED;
}
}
Example: Article without setters
class Article {
// ...
public function update(Author $author, $text, $state, DateTime $published = null) {
if ($this->state === self::STATE_DELETED) {
throw new ArticleIsDeletedException($this);
}
$this->author = $author;
$this->text = $text;
$this->state = $state;
if ($state === self::STATE_PUBLISHED) {
$this->published = $published ?: new DateTime();
} elseif ($state === self::STATE_UNPUBLISHED) {
$this->published = null;
}
}
}
What Is an Object Anyway?
Object Oriented Programming
Objects have both data (their properties) and behavior (their methods).
Objects model real-world behavior, concepts and relationships.
Encapsulation principle tells us to hide the details about the data and focus solely
on the behavior - the public methods of our objects (“Tell, Don’t Ask”).
In PHP it is easy to combine procedural and object-oriented programming.
Example: Bank Account Object
class BankAccount {
private $balance;
public function __construct(Money $balance) {
$this->balance = $balance;
}
public function deposit(Money $amount) {
$this->balance = $this->balance->add($amount);
}
public function withdraw(Money $amount) {
if ($this->balance->isLessThan($amount)) {
throw new InsufficientFundsException($balance, $amount);
}
$this->balance = $this->balance->subtract($amount);
}
}
Anemic / Rich Domain Model
Let’s Define Some Terms First
Domain: Most common definition: “A sphere of knowledge or activity.”
It’s basically the subject area of your application (eg. an online store or news site).
Domain Model: System of abstractions describing part of the domain that can be
used to solve problems. Simplification of the real world.
Domain Object: Object that is part of the domain model (eg. Product, Order, …).
Business Logic: High-level logic reflecting the real-world business rules.
Anemic Domain Model
No business logic in domain objects
Clearly separates logic and data
Violates object encapsulation
Works well for simple applications
Leads to procedural programming
Called an anti-pattern by M. Fowler
Business logic mainly in domain objects
Domain objects encapsulate inner data,
offer meaningful behavior
Data integrity kept by the encapsulation
Better choice for complex domain
models
Rich Domain Model
Anemic Domain Model Rich Domain Model
class Worker {
function getVelocity() {
return $this->velocity;
}
function setVelocity($velocity) {
$this->velocity = $velocity;
}
}
class WorkerService {
function work(Worker $w, Task $t, $time) {
$progress = $t->getProgress();
$progress += $w->getVelocity() * $time;
$t->setProgress($progress);
}
}
class Worker {
function __construct($velocity) {
$this->velocity = $velocity;
}
function work(Task $task, $time) {
$progress = $this->velocity * $time;
$task->makeProgress($progress);
}
}
The Problem Lies in Setters
Setters Do Not Exist in the Real World
Setters have no meaning in the real world:
● A writer does not set a “published” state to an article, he/she publishes it.
● Customers do not set a “paid” status to an order, they pay for it.
● Your happy boss does not set a higher salary to you, he/she raises it.
There is always a better, more expressive, alternative to a setter.
Expressive statements lead to more readable code.
Nobody Expects The Setters To Do Stuff
Similarly to adding logic to a CRUD
update, you might feel the need to add
some business logic to your setter.
The problem with this is that nobody
expects setters to do anything beside
setting the property.
An unexpected behavior leads to bugs.
class Order {
// ...
public function setStatus($status) {
if (!$this->isValidStatus($status)) {
throw new InvalidArgumentException();
}
$this->status = $status;
if ($status === self::STATUS_PAID) {
$this->mailService->sendOrderPaidMail(
$this->orderNumber, $this->customer
);
}
}
}
Nobody Expects The Setters To Do Stuff
Similarly to adding logic to a CRUD
update, you might feel the need to add
some business logic to your setter.
The problem with this is that nobody
expects setters to do anything beside
setting the property.
An unexpected behavior leads to bugs.
class Order {
// ...
public function pay() {
$this->status = self::STATUS_PAID;
$this->mailService->sendOrderPaidMail(
$this->orderNumber, $this->customer
);
}
public function cancel() {
$this->status = self::STATUS_CANCELLED;
}
}
An Update in CRUD Is Similar to a Setter
Generic update method in CRUD is similar to a setter:
● It does not have a real-world meaning.
● There are better alternatives based on real scenarios to be implemented.
For example, by “updating” an article we mean “rewriting” it and possibly
“publishing”, “unpublishing” or “deleting” it.
Conclusion and
Recommendations
Focus on Real Scenarios
By building your application around you domain objects and their behavior you
can get expressive code that is easier to understand, use and maintain.
Concept of “setting” or “updating” to too generic to be meaningful.
Your API should be focused on real scenarios, real use-cases. This will keep the
API clean and intuitive and it will help you keep the integrity of your data.
Think About the Way You Program
There is no best way, no silver bullet. And there probably never will be one.
Keep in mind the techniques of object-oriented programming, encapsulation
principle, focusing on the behavior.
Knowing about the two extremes will help you improve the design of your
application and choose the proper solution for your project.
Need CRUD methods? Add a Layer.
If you for some reason want to
allow classical CRUD methods,
you can build it on top of your
internal API.
You can use Adapter pattern for
this task.
class Article {
// ...
public function update(...) {
if ($this->state === self::STATE_DELETED) {
throw new ArticleIsDeletedEx($this);
}
$this->author = $author;
$this->text = $text;
$this->state = $state;
if ($state === self::STATE_PUBLISHED) {
$this->published = $published ?: new DateTime();
} elseif ($state === self::STATE_UNPUBLISHED) {
$this->published = null;
}
}
}
Need CRUD methods? Add a Layer.
If you for some reason want to
allow classical CRUD methods,
you can build it on top of your
internal API.
You can use Adapter pattern for
this task.
class ArticleCrudAdapter {
// ...
public function update(...) {
if ($this->article->isDeleted()) {
throw new ArticleIsDeletedEx($this->article);
}
$this->article->rewrite($text, $author);
switch ($state) {
case Article::STATE_PUBLISHED:
$this->article->publish($published); break;
case Article::STATE_UNPUBLISHED:
$this->article->unpublish(); break;
case Article::STATE_DELETED:
$this->article->delete(); break;
}
}
}
It Is About the Balance
Every way has its tradeoffs and, as always, it is about the balance.
Focusing on real-world use-cases helps to maintain integrity and usability.
Integration with other libraries or components is easier with generic methods.
When developing Shopsys Framework we try to keep that in mind, and take
inspiration from Rich Domain Model.
See for yourself, join closed beta: https://www.shopsys-framework.com
Thanks for listening!
Let’s get down to your questions!

More Related Content

What's hot

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
XSolve
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
Arnaud Langlade
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Colin O'Dell
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
Hugo Hamon
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
XSolve
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Kacper Gunia
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
Nate Abele
 
Oops in php
Oops in phpOops in php
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
James Titcumb
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
Kacper Gunia
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5 Wildan Maulana
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
Kacper Gunia
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
Manel Sellés
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
Łukasz Chruściel
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
Kacper Gunia
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
Konstantin Kudryashov
 

What's hot (20)

PHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolvePHPCon 2016: PHP7 by Witek Adamus / XSolve
PHPCon 2016: PHP7 by Witek Adamus / XSolve
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)Code moi une RH! (PHP tour 2017)
Code moi une RH! (PHP tour 2017)
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you needDutch PHP Conference - PHPSpec 2 - The only Design Tool you need
Dutch PHP Conference - PHPSpec 2 - The only Design Tool you need
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Oops in php
Oops in phpOops in php
Oops in php
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Design Patterns in PHP5
Design Patterns in PHP5 Design Patterns in PHP5
Design Patterns in PHP5
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
When cqrs meets event sourcing
When cqrs meets event sourcingWhen cqrs meets event sourcing
When cqrs meets event sourcing
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 

Similar to Why is crud a bad idea - focus on real scenarios

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
Jonathan Wage
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
Lars Jankowfsky
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
Marcello Duarte
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
Michelangelo van Dam
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
SWIFTotter Solutions
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
Abbas Ali
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
Konstantin Kudryashov
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
Yevhen Kotelnytskyi
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
Yevhen Kotelnytskyi
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
Elena Kolevska
 
Fatc
FatcFatc
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
Tagged Social
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
Marcello Duarte
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Ivan Chepurnyi
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
Alexander Varwijk
 
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
PROIDEA
 

Similar to Why is crud a bad idea - focus on real scenarios (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Framework
FrameworkFramework
Framework
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
PHPSpec BDD Framework
PHPSpec BDD FrameworkPHPSpec BDD Framework
PHPSpec BDD Framework
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
Zend framework service
Zend framework serviceZend framework service
Zend framework service
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Tidy Up Your Code
Tidy Up Your CodeTidy Up Your Code
Tidy Up Your Code
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?Как получить чёрный пояс по WordPress?
Как получить чёрный пояс по WordPress?
 
Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0Как получить чёрный пояс по WordPress? v2.0
Как получить чёрный пояс по WordPress? v2.0
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Fatc
FatcFatc
Fatc
 
PHP Unit Testing
PHP Unit TestingPHP Unit Testing
PHP Unit Testing
 
PHPSpec BDD for PHP
PHPSpec BDD for PHPPHPSpec BDD for PHP
PHPSpec BDD for PHP
 
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for PerformanceMeet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
Meet Magento Sweden - Magento 2 Layout and Code Compilation for Performance
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
 

More from Divante

The eCommerce Platforms in the Global Setup
The eCommerce Platforms in the Global Setup	The eCommerce Platforms in the Global Setup
The eCommerce Platforms in the Global Setup
Divante
 
eCommerce Trends 2020
eCommerce Trends 2020eCommerce Trends 2020
eCommerce Trends 2020
Divante
 
Async & Bulk REST API new possibilities of communication between systems
Async & Bulk REST API new possibilities of communication  between systemsAsync & Bulk REST API new possibilities of communication  between systems
Async & Bulk REST API new possibilities of communication between systems
Divante
 
Magento Functional Testing Framework a way to seriously write automated tests...
Magento Functional Testing Framework a way to seriously write automated tests...Magento Functional Testing Framework a way to seriously write automated tests...
Magento Functional Testing Framework a way to seriously write automated tests...
Divante
 
Die Top 10 Progressive Web Apps in der Modernbranche
Die Top 10 Progressive Web Apps in der ModernbrancheDie Top 10 Progressive Web Apps in der Modernbranche
Die Top 10 Progressive Web Apps in der Modernbranche
Divante
 
progressive web apps - pwa as a game changer for e-commerce - meet magento i...
 progressive web apps - pwa as a game changer for e-commerce - meet magento i... progressive web apps - pwa as a game changer for e-commerce - meet magento i...
progressive web apps - pwa as a game changer for e-commerce - meet magento i...
Divante
 
Customer churn - how to stop it?
Customer churn - how to stop it?Customer churn - how to stop it?
Customer churn - how to stop it?
Divante
 
eCommerce trends 2019 by Divante.co
eCommerce trends 2019 by Divante.coeCommerce trends 2019 by Divante.co
eCommerce trends 2019 by Divante.co
Divante
 
How to create a Vue Storefront theme
How to create a Vue Storefront themeHow to create a Vue Storefront theme
How to create a Vue Storefront theme
Divante
 
Game changer for e-commerce - Vue Storefront - open source pwa
Game changer for e-commerce - Vue Storefront - open source pwa Game changer for e-commerce - Vue Storefront - open source pwa
Game changer for e-commerce - Vue Storefront - open source pwa
Divante
 
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speechVue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Divante
 
How to successfully onboard end-clients to a B2B Platform - Magento Imagine ...
How to successfully onboard  end-clients to a B2B Platform - Magento Imagine ...How to successfully onboard  end-clients to a B2B Platform - Magento Imagine ...
How to successfully onboard end-clients to a B2B Platform - Magento Imagine ...
Divante
 
eCommerce trends from 2017 to 2018 by Divante.co
eCommerce trends from 2017 to 2018 by Divante.coeCommerce trends from 2017 to 2018 by Divante.co
eCommerce trends from 2017 to 2018 by Divante.co
Divante
 
Designing for PWA (Progressive Web Apps)
Designing for PWA (Progressive Web Apps)Designing for PWA (Progressive Web Apps)
Designing for PWA (Progressive Web Apps)
Divante
 
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentationvue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
Divante
 
Pimcore Overview - Pimcore5
Pimcore Overview - Pimcore5Pimcore Overview - Pimcore5
Pimcore Overview - Pimcore5
Divante
 
Pimcore E-Commerce Framework - Pimcore5
Pimcore E-Commerce Framework - Pimcore5Pimcore E-Commerce Framework - Pimcore5
Pimcore E-Commerce Framework - Pimcore5
Divante
 
The biggest stores on Magento
The biggest stores on MagentoThe biggest stores on Magento
The biggest stores on Magento
Divante
 
B2B Commerce - how to become successful
B2B Commerce - how to become successfulB2B Commerce - how to become successful
B2B Commerce - how to become successful
Divante
 
Budgeting in SCRUM by Divante
Budgeting in SCRUM by DivanteBudgeting in SCRUM by Divante
Budgeting in SCRUM by Divante
Divante
 

More from Divante (20)

The eCommerce Platforms in the Global Setup
The eCommerce Platforms in the Global Setup	The eCommerce Platforms in the Global Setup
The eCommerce Platforms in the Global Setup
 
eCommerce Trends 2020
eCommerce Trends 2020eCommerce Trends 2020
eCommerce Trends 2020
 
Async & Bulk REST API new possibilities of communication between systems
Async & Bulk REST API new possibilities of communication  between systemsAsync & Bulk REST API new possibilities of communication  between systems
Async & Bulk REST API new possibilities of communication between systems
 
Magento Functional Testing Framework a way to seriously write automated tests...
Magento Functional Testing Framework a way to seriously write automated tests...Magento Functional Testing Framework a way to seriously write automated tests...
Magento Functional Testing Framework a way to seriously write automated tests...
 
Die Top 10 Progressive Web Apps in der Modernbranche
Die Top 10 Progressive Web Apps in der ModernbrancheDie Top 10 Progressive Web Apps in der Modernbranche
Die Top 10 Progressive Web Apps in der Modernbranche
 
progressive web apps - pwa as a game changer for e-commerce - meet magento i...
 progressive web apps - pwa as a game changer for e-commerce - meet magento i... progressive web apps - pwa as a game changer for e-commerce - meet magento i...
progressive web apps - pwa as a game changer for e-commerce - meet magento i...
 
Customer churn - how to stop it?
Customer churn - how to stop it?Customer churn - how to stop it?
Customer churn - how to stop it?
 
eCommerce trends 2019 by Divante.co
eCommerce trends 2019 by Divante.coeCommerce trends 2019 by Divante.co
eCommerce trends 2019 by Divante.co
 
How to create a Vue Storefront theme
How to create a Vue Storefront themeHow to create a Vue Storefront theme
How to create a Vue Storefront theme
 
Game changer for e-commerce - Vue Storefront - open source pwa
Game changer for e-commerce - Vue Storefront - open source pwa Game changer for e-commerce - Vue Storefront - open source pwa
Game changer for e-commerce - Vue Storefront - open source pwa
 
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speechVue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
Vue Storefront - Progressive Web App for Magento (1.9, 2.x) - MM18DE speech
 
How to successfully onboard end-clients to a B2B Platform - Magento Imagine ...
How to successfully onboard  end-clients to a B2B Platform - Magento Imagine ...How to successfully onboard  end-clients to a B2B Platform - Magento Imagine ...
How to successfully onboard end-clients to a B2B Platform - Magento Imagine ...
 
eCommerce trends from 2017 to 2018 by Divante.co
eCommerce trends from 2017 to 2018 by Divante.coeCommerce trends from 2017 to 2018 by Divante.co
eCommerce trends from 2017 to 2018 by Divante.co
 
Designing for PWA (Progressive Web Apps)
Designing for PWA (Progressive Web Apps)Designing for PWA (Progressive Web Apps)
Designing for PWA (Progressive Web Apps)
 
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentationvue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
vue-storefront - PWA eCommerce for Magento2 MM17NYC presentation
 
Pimcore Overview - Pimcore5
Pimcore Overview - Pimcore5Pimcore Overview - Pimcore5
Pimcore Overview - Pimcore5
 
Pimcore E-Commerce Framework - Pimcore5
Pimcore E-Commerce Framework - Pimcore5Pimcore E-Commerce Framework - Pimcore5
Pimcore E-Commerce Framework - Pimcore5
 
The biggest stores on Magento
The biggest stores on MagentoThe biggest stores on Magento
The biggest stores on Magento
 
B2B Commerce - how to become successful
B2B Commerce - how to become successfulB2B Commerce - how to become successful
B2B Commerce - how to become successful
 
Budgeting in SCRUM by Divante
Budgeting in SCRUM by DivanteBudgeting in SCRUM by Divante
Budgeting in SCRUM by Divante
 

Recently uploaded

test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
Arif0071
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
GTProductions1
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
laozhuseo02
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
ufdana
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
JeyaPerumal1
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
keoku
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
Rogerio Filho
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
natyesu
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
3ipehhoa
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
nirahealhty
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
3ipehhoa
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
3ipehhoa
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Sanjeev Rampal
 
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
laozhuseo02
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
JungkooksNonexistent
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Brad Spiegel Macon GA
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
eutxy
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
Gal Baras
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
Javier Lasa
 

Recently uploaded (20)

test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
APNIC Foundation, presented by Ellisha Heppner at the PNG DNS Forum 2024
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
 

Why is crud a bad idea - focus on real scenarios

  • 1. Why Is CRUD a Bad Idea Focus on Real Scenarios
  • 2. Petr Heinz More than 8 years of programming experience. Loves clean code, regular expressions and clever design. Dedicated last year to developing the Shopsys Framework, open source e-commerce framework made with passion on Symfony 3. ✉ petr.heinz@shopsys.com
  • 4. Create, Read, Update and Delete Four basic functions of an persistent storage, often used as an API. Can be mapped to SQL statements: INSERT SELECT UPDATE DELETE Can be mapped to HTTP methods (used in REST APIs): PUT GET POST DELETE
  • 5. Example: Article class Article { private $author, $text, $state, $published; public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } public function setText($text) { $this->text = $text; } // ... } class ArticleController { public function create(...) { // ... } public function update(...) { // ... $article->setAuthor($author); $article->setText($text); $article->setState($state); $article->setPublished($published); } public function delete(...) { // ... } }
  • 6. Entities Must Follow Business Rules Entities are often constrained by business rules and the consistency must be kept. ● Company customer must have VAT ID filled in his account. ● Sold out product must be hidden. ● Article in published state must have published date. This is difficult to achieve in the previous example. That’s because all article attributes can be changed independently. Developers are not restricted in the way they interact with the object.
  • 7. Example: Article without setters class Article { const STATE_UNPUBLISHED = 1; const STATE_PUBLISHED = 2; const STATE_DELETED = 3; private $author, $text, $state, $published; public function __construct(Author $author, $text, $state, DateTime $published = null) { // ... } public function update(Author $author, $text, $state, DateTime $published = null) { // ... } public function delete() { $this->state = self::STATE_DELETED; } }
  • 8. Example: Article without setters class Article { // ... public function update(Author $author, $text, $state, DateTime $published = null) { if ($this->state === self::STATE_DELETED) { throw new ArticleIsDeletedException($this); } $this->author = $author; $this->text = $text; $this->state = $state; if ($state === self::STATE_PUBLISHED) { $this->published = $published ?: new DateTime(); } elseif ($state === self::STATE_UNPUBLISHED) { $this->published = null; } } }
  • 9. What Is an Object Anyway?
  • 10. Object Oriented Programming Objects have both data (their properties) and behavior (their methods). Objects model real-world behavior, concepts and relationships. Encapsulation principle tells us to hide the details about the data and focus solely on the behavior - the public methods of our objects (“Tell, Don’t Ask”). In PHP it is easy to combine procedural and object-oriented programming.
  • 11. Example: Bank Account Object class BankAccount { private $balance; public function __construct(Money $balance) { $this->balance = $balance; } public function deposit(Money $amount) { $this->balance = $this->balance->add($amount); } public function withdraw(Money $amount) { if ($this->balance->isLessThan($amount)) { throw new InsufficientFundsException($balance, $amount); } $this->balance = $this->balance->subtract($amount); } }
  • 12. Anemic / Rich Domain Model
  • 13. Let’s Define Some Terms First Domain: Most common definition: “A sphere of knowledge or activity.” It’s basically the subject area of your application (eg. an online store or news site). Domain Model: System of abstractions describing part of the domain that can be used to solve problems. Simplification of the real world. Domain Object: Object that is part of the domain model (eg. Product, Order, …). Business Logic: High-level logic reflecting the real-world business rules.
  • 14. Anemic Domain Model No business logic in domain objects Clearly separates logic and data Violates object encapsulation Works well for simple applications Leads to procedural programming Called an anti-pattern by M. Fowler Business logic mainly in domain objects Domain objects encapsulate inner data, offer meaningful behavior Data integrity kept by the encapsulation Better choice for complex domain models Rich Domain Model
  • 15. Anemic Domain Model Rich Domain Model class Worker { function getVelocity() { return $this->velocity; } function setVelocity($velocity) { $this->velocity = $velocity; } } class WorkerService { function work(Worker $w, Task $t, $time) { $progress = $t->getProgress(); $progress += $w->getVelocity() * $time; $t->setProgress($progress); } } class Worker { function __construct($velocity) { $this->velocity = $velocity; } function work(Task $task, $time) { $progress = $this->velocity * $time; $task->makeProgress($progress); } }
  • 16. The Problem Lies in Setters
  • 17. Setters Do Not Exist in the Real World Setters have no meaning in the real world: ● A writer does not set a “published” state to an article, he/she publishes it. ● Customers do not set a “paid” status to an order, they pay for it. ● Your happy boss does not set a higher salary to you, he/she raises it. There is always a better, more expressive, alternative to a setter. Expressive statements lead to more readable code.
  • 18. Nobody Expects The Setters To Do Stuff Similarly to adding logic to a CRUD update, you might feel the need to add some business logic to your setter. The problem with this is that nobody expects setters to do anything beside setting the property. An unexpected behavior leads to bugs. class Order { // ... public function setStatus($status) { if (!$this->isValidStatus($status)) { throw new InvalidArgumentException(); } $this->status = $status; if ($status === self::STATUS_PAID) { $this->mailService->sendOrderPaidMail( $this->orderNumber, $this->customer ); } } }
  • 19. Nobody Expects The Setters To Do Stuff Similarly to adding logic to a CRUD update, you might feel the need to add some business logic to your setter. The problem with this is that nobody expects setters to do anything beside setting the property. An unexpected behavior leads to bugs. class Order { // ... public function pay() { $this->status = self::STATUS_PAID; $this->mailService->sendOrderPaidMail( $this->orderNumber, $this->customer ); } public function cancel() { $this->status = self::STATUS_CANCELLED; } }
  • 20. An Update in CRUD Is Similar to a Setter Generic update method in CRUD is similar to a setter: ● It does not have a real-world meaning. ● There are better alternatives based on real scenarios to be implemented. For example, by “updating” an article we mean “rewriting” it and possibly “publishing”, “unpublishing” or “deleting” it.
  • 22. Focus on Real Scenarios By building your application around you domain objects and their behavior you can get expressive code that is easier to understand, use and maintain. Concept of “setting” or “updating” to too generic to be meaningful. Your API should be focused on real scenarios, real use-cases. This will keep the API clean and intuitive and it will help you keep the integrity of your data.
  • 23. Think About the Way You Program There is no best way, no silver bullet. And there probably never will be one. Keep in mind the techniques of object-oriented programming, encapsulation principle, focusing on the behavior. Knowing about the two extremes will help you improve the design of your application and choose the proper solution for your project.
  • 24. Need CRUD methods? Add a Layer. If you for some reason want to allow classical CRUD methods, you can build it on top of your internal API. You can use Adapter pattern for this task. class Article { // ... public function update(...) { if ($this->state === self::STATE_DELETED) { throw new ArticleIsDeletedEx($this); } $this->author = $author; $this->text = $text; $this->state = $state; if ($state === self::STATE_PUBLISHED) { $this->published = $published ?: new DateTime(); } elseif ($state === self::STATE_UNPUBLISHED) { $this->published = null; } } }
  • 25. Need CRUD methods? Add a Layer. If you for some reason want to allow classical CRUD methods, you can build it on top of your internal API. You can use Adapter pattern for this task. class ArticleCrudAdapter { // ... public function update(...) { if ($this->article->isDeleted()) { throw new ArticleIsDeletedEx($this->article); } $this->article->rewrite($text, $author); switch ($state) { case Article::STATE_PUBLISHED: $this->article->publish($published); break; case Article::STATE_UNPUBLISHED: $this->article->unpublish(); break; case Article::STATE_DELETED: $this->article->delete(); break; } } }
  • 26. It Is About the Balance Every way has its tradeoffs and, as always, it is about the balance. Focusing on real-world use-cases helps to maintain integrity and usability. Integration with other libraries or components is easier with generic methods. When developing Shopsys Framework we try to keep that in mind, and take inspiration from Rich Domain Model. See for yourself, join closed beta: https://www.shopsys-framework.com
  • 27. Thanks for listening! Let’s get down to your questions!