SlideShare a Scribd company logo
Herman Peeren
SweetlakePHP
August 2015
DCIData - Context - Interaction
Dci in PHP
Trygve Reenskaug James Coplien (Cope)
Dci in PHP
playing roles
not all behaviour at the same time
Dci in PHP
This picture and on coming pages example from Victor Savkin:
http://www.sitepoint.com/dci-the-evolution-of-the-object-oriented-paradigm/
Dci in PHP
Dci in PHP
Dci in PHP
Dci in PHP
what the system is
< >
what the system does
•	anemic model, “data”
•	adding behaviour in a “context”
•	behaviour grouped in roles
•	context = use case, scenarios
•	model matches mental model
•	readability of object oriented code
•	object oriented < > class oriented
•	 http://fulloo.info/Documents/
•	 http://en.wikipedia.org/wiki/Data,_context_and_interaction
•	 https://groups.google.com/forum/#!forum/object-composition
“Wrapper” implementation
•	Instantiate the Roles and constructor-inject a RolePlayer-
object in them.
•	Leads to “object schizophrenia”: what is the $this in a
Role-method referring to? It should be the same object as
the $this in the RolePlayer.
https://en.wikipedia.org/wiki/Schizophrenia_%28object-oriented_programming%29
•	Big NO-NO and showstopper in DCI.
Some implementations of DCI in PHP
that are none or less “wrapper”:
•	CoreDCI: can be used in PHP 5.3 (no traits). A method-injection PHP-implementa-
tion from 2010 using naming conventions like r Rolename Actions-classes.
Used in http://code.google.com/p/waxphp/.
See http://code.google.com/p/php-coredci/wiki/UsingCoreDCI
•	Fatty: originally for Laravel. Uses closure object binding (in PHP 5.4).
See http://kirkbushell.me/data-context-interaction-for-php/.
Code on https://github.com/kirkbushell/fatty.
•	the “reverse wrapper” (object wraps the role rather than the role wrap-
ping the object), which also results in methods of a role being injected in a data ob-
ject (with examples in PHP 5.3 and using traits).
See https://github.com/mbrowne/dci-php.
Discussion: https://groups.google.com/d/msg/object-composition/YDKfrGuLXDo/
pRirNWtks4oJ
CoreDCI: can be used in PHP 5.3 (no traits). A method-injection PHP-implemen-
tation that gets the rolename for the objects from the context’s execute() signature. You
need to implement an interface with the Rolename in the roleplaying object. That doesn’t
make it very flexible if you want to add behaviour. Also: what is $this in Role methods?
class Account
extends DCIObject
implements rMoneySource, rMoneySink {
protected $balance;
function __construct($initial_balance) {
parent::__construct();
$this->balance = $initial_balance;
}
function Withdraw($amount) {
if ($amount <= $this->balance) {
$this->balance -= $amount;
return $amount;
}
else
throw new DCIException(“Insufficient Funds”,”Tried to withdraw $amount<br />{$this->balance} available.”);
}
function Deposit($amount) {
$this->balance += $amount;
}
class TransferCtx extends Context {
function Execute(rMoneySource $source, rMoneySink $sink, $amount) {
parent::Execute();
$source->TransferFunds($sink,$amount);
}
}
function GetBalance() { return $this->balance; }
}
Fatty: originally for Laravel. Uses closure object binding (in PHP 5.4). Example only
shows how to use instead of inheritance.
see:
•	 http://php.net/manual/en/closure.bind.php#110845 for example adding method
•	 https://gist.github.com/mbrowne/5047982 for a similar implementation
Closure object binding:
public function addMethod($methodName, $methodCallable)
{
if (!is_callable($methodCallable)) {
throw new InvalidArgumentException(‘Second param must be callable’);
}
$this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class());
}
public function __call($methodName, array $args)
{
if (isset($this->methods[$methodName])) {
return call_user_func_array($this->methods[$methodName], $args);
}
throw RunTimeException(‘There is no method with the given name to call’);
}
the “reverse wrapper” (object wraps the role rather than the role wrapping
the object), which also results in methods of a role being injected in a data object.
In each RolePlayer:
function addRole($roleName, Context $context) {
		$this->_setCurrentContext($context);		
		 $roleClassName = $this->currentContextClassName.’Roles’.$roleName;
		
		 if (!class_exists($roleClassName, false)) {
			 throw new InvalidArgumentException(“The role ‘$roleClassName’ is not defined
				 (it should be defined in the same *file* as the context to which it belongs).”);}
		
		 $role = new $roleClassName($this, $context);
		
		$this->bindRoleMethods($role);
		return $this;
	}
function __call($methodName, $args) {
		 if (isset($this->roleMethods[$this->currentContextClassName][$methodName])) {
			$role = $this->roleMethods[$this->currentContextClassName][$methodName];
		}
		 if (!isset($role) || !method_exists($role, $methodName)) {
// error handling...
}
		 //Call $role->$methodName() with the given arguments
		 return call_user_func_array(array($role, $methodName), $args);
	}
Mixins from Nooku Framework
•	 Nooku Framework started as a new framework for Joomla. It had mixins before we
had traits in PHP.
•	 Mixins are methods mixed into an object (not into a class, like traits):
$object->mixin($mixin);
•	 DCI roles can be implemented as mixins. I made a mixout() method to get rid of the
methods when leaving the context.
•	 it is “under the hood” a kind of reverse wrapper: every object has a mixin()-method
and when a method is called is is looked up in the list and then called on the mixin
where it is defined.
public function __call($method, $arguments)
{
if (isset($this->_mixed_methods[$method]))
{ //etc.
$result = call_user_func_array(array($mixin, $method), $arguments);
}
...
Nooku’s __call() also looks at closures and other mixed-in methods.
Here the part where the mixin is an object:
elseif(is_object($this->_mixed_methods[$method]))
{
$mixin = $this->_mixed_methods[$method];
//Switch the mixin’s attached mixer
$mixin->setMixer($this);
// Call_user_func_array is ~3 times slower than direct method calls. I say: not worth that ugly switch
switch (count($arguments))
{
case 0 :
$result = $mixin->$method();
break;
case 1 :
$result = $mixin->$method($arguments[0]);
break;
case 2 :
$result = $mixin->$method($arguments[0], $arguments[1]);
break;
case 3 :
$result = $mixin->$method($arguments[0], $arguments[1], $arguments[2]);
break;
default:
// Resort to using call_user_func_array for many segments
$result = call_user_func_array(array($mixin, $method), $arguments);
}
Work in progress... some thoughts:
“Data” don’t exist
•	in Functional Programming
•	and Event Sourcing
Data, state is
•	a left fold
•	a snapshot
•	a result of a stream of events
•	then what about
DATA? - Context - Interaction
•	if we implement that with Event Sourcing
•	we have events as a result of interacting roles
•	a “context” instead of an “aggregate”
•	roles played by a reconstituted stream of events
•	can we learn from DCI for better
Domain Driven Design?
•	behaviour related to use case / scenarios
•	adding behaviour at runtime (roles)
•	better names (context, role)
•	algorithm more a whole, readability
•	a model is not a tree...
Take away:
•	separating behaviour from data
Behaviour
is better composable
than objects
Herman Peeren
August 2015
herman@yepr.nl

More Related Content

PDF
Dependency Injection
PDF
Design Patterns in PHP5
PDF
Beyond the DOM: Sane Structure for JS Apps
PDF
Design how your objects talk through mocking
PDF
06 jQuery #burningkeyboards
PDF
05 JavaScript #burningkeyboards
PDF
JavaScript Fundamentals with Angular and Lodash
PDF
Lodash js
Dependency Injection
Design Patterns in PHP5
Beyond the DOM: Sane Structure for JS Apps
Design how your objects talk through mocking
06 jQuery #burningkeyboards
05 JavaScript #burningkeyboards
JavaScript Fundamentals with Angular and Lodash
Lodash js

What's hot (20)

PDF
Chaining and function composition with lodash / underscore
KEY
Zf Zend Db by aida
PPTX
jQuery
PDF
PHPCon 2016: PHP7 by Witek Adamus / XSolve
PDF
Min-Maxing Software Costs
PDF
Migrating to dependency injection
PPTX
Symfony2 your way
PDF
Coffeescript a z
PDF
Your code sucks, let's fix it - DPC UnCon
PDF
The State of Lithium
PDF
Doctrine For Beginners
PDF
Symfony2 from the Trenches
PDF
Doctrine MongoDB Object Document Mapper
PDF
ZendCon2010 Doctrine MongoDB ODM
PDF
Lithium: The Framework for People Who Hate Frameworks
KEY
Jquery Fundamentals
PDF
Symfony Day 2010 Doctrine MongoDB ODM
PDF
CakeFest 2013 keynote
PPTX
Javascript And J Query
PDF
Modularity and Layered Data Model
Chaining and function composition with lodash / underscore
Zf Zend Db by aida
jQuery
PHPCon 2016: PHP7 by Witek Adamus / XSolve
Min-Maxing Software Costs
Migrating to dependency injection
Symfony2 your way
Coffeescript a z
Your code sucks, let's fix it - DPC UnCon
The State of Lithium
Doctrine For Beginners
Symfony2 from the Trenches
Doctrine MongoDB Object Document Mapper
ZendCon2010 Doctrine MongoDB ODM
Lithium: The Framework for People Who Hate Frameworks
Jquery Fundamentals
Symfony Day 2010 Doctrine MongoDB ODM
CakeFest 2013 keynote
Javascript And J Query
Modularity and Layered Data Model
Ad

Similar to Dci in PHP (20)

PPTX
PDF
Advanced PHP Simplified - Sunshine PHP 2018
PDF
PHP Performance Trivia
PPTX
Object oreinted php | OOPs
PPTX
PHP Starter Application
PDF
Data Context Interaction - What is it good for?
ODP
Rich domain model with symfony 2.5 and doctrine 2.5
PPT
Class 7 - PHP Object Oriented Programming
PPTX
Adding Dependency Injection to Legacy Applications
PDF
Advanced PHP Simplified
PPT
Advanced php
PDF
ZF2 Presentation @PHP Tour 2011 in Lille
PDF
PHP 8: Process & Fixing Insanity
PDF
Beyond MVC: from Model to Domain
PDF
OOP in PHP
PPTX
Php meetup 20130912 reflection
PPT
PPT
Easy rest service using PHP reflection api
PDF
Code Generation in PHP - PHPConf 2015
PDF
Object Oriented PHP - PART-1
Advanced PHP Simplified - Sunshine PHP 2018
PHP Performance Trivia
Object oreinted php | OOPs
PHP Starter Application
Data Context Interaction - What is it good for?
Rich domain model with symfony 2.5 and doctrine 2.5
Class 7 - PHP Object Oriented Programming
Adding Dependency Injection to Legacy Applications
Advanced PHP Simplified
Advanced php
ZF2 Presentation @PHP Tour 2011 in Lille
PHP 8: Process & Fixing Insanity
Beyond MVC: from Model to Domain
OOP in PHP
Php meetup 20130912 reflection
Easy rest service using PHP reflection api
Code Generation in PHP - PHPConf 2015
Object Oriented PHP - PART-1
Ad

More from Herman Peeren (20)

PDF
ProjectionalForms-2023-11-14.pdf
PDF
ExtensionGenerator-JoomlaDagen2023-slides.pdf
PDF
Cut & Shave
PDF
Programmeren, talen en het begrijpen van de wereld
PDF
Improve our PHP code with ideas from Functional Programming
PDF
DCI DDD-BE April 2015
PDF
Design patterns illustrated-2015-03
PDF
Event Sourcing
PDF
Next Generation Joomla!
PDF
Behat, Behavioral Driven Development (BDD) in PHP
PDF
Design patterns illustrated 010PHP
PDF
Print, geen kunst aan
PDF
Jooctrine - Doctrine ORM in Joomla!
PDF
#jd12nl Joomla 2.5 extensies
PDF
#jd12nl Seblod 2
PDF
Jug010 120320-templates
PDF
Joomla2.0 architecture
PDF
Webservices: connecting Joomla! with other programs.
PDF
Commercial gpljoomla
PDF
Design Patterns Illustrated
ProjectionalForms-2023-11-14.pdf
ExtensionGenerator-JoomlaDagen2023-slides.pdf
Cut & Shave
Programmeren, talen en het begrijpen van de wereld
Improve our PHP code with ideas from Functional Programming
DCI DDD-BE April 2015
Design patterns illustrated-2015-03
Event Sourcing
Next Generation Joomla!
Behat, Behavioral Driven Development (BDD) in PHP
Design patterns illustrated 010PHP
Print, geen kunst aan
Jooctrine - Doctrine ORM in Joomla!
#jd12nl Joomla 2.5 extensies
#jd12nl Seblod 2
Jug010 120320-templates
Joomla2.0 architecture
Webservices: connecting Joomla! with other programs.
Commercial gpljoomla
Design Patterns Illustrated

Recently uploaded (20)

PDF
17 Powerful Integrations Your Next-Gen MLM Software Needs
PDF
Download FL Studio Crack Latest version 2025 ?
PPTX
history of c programming in notes for students .pptx
PDF
Designing Intelligence for the Shop Floor.pdf
PDF
Autodesk AutoCAD Crack Free Download 2025
PPTX
Advanced SystemCare Ultimate Crack + Portable (2025)
PDF
wealthsignaloriginal-com-DS-text-... (1).pdf
PDF
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
PPTX
Patient Appointment Booking in Odoo with online payment
PDF
Design an Analysis of Algorithms II-SECS-1021-03
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
CapCut Video Editor 6.8.1 Crack for PC Latest Download (Fully Activated) 2025
PPTX
Reimagine Home Health with the Power of Agentic AI​
PDF
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
PPTX
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
PDF
Complete Guide to Website Development in Malaysia for SMEs
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev
17 Powerful Integrations Your Next-Gen MLM Software Needs
Download FL Studio Crack Latest version 2025 ?
history of c programming in notes for students .pptx
Designing Intelligence for the Shop Floor.pdf
Autodesk AutoCAD Crack Free Download 2025
Advanced SystemCare Ultimate Crack + Portable (2025)
wealthsignaloriginal-com-DS-text-... (1).pdf
EN-Survey-Report-SAP-LeanIX-EA-Insights-2025.pdf
Patient Appointment Booking in Odoo with online payment
Design an Analysis of Algorithms II-SECS-1021-03
Wondershare Filmora 15 Crack With Activation Key [2025
CapCut Video Editor 6.8.1 Crack for PC Latest Download (Fully Activated) 2025
Reimagine Home Health with the Power of Agentic AI​
Product Update: Alluxio AI 3.7 Now with Sub-Millisecond Latency
Internet Downloader Manager (IDM) Crack 6.42 Build 41
How to Make Money in the Metaverse_ Top Strategies for Beginners.pdf
Log360_SIEM_Solutions Overview PPT_Feb 2020.pptx
Complete Guide to Website Development in Malaysia for SMEs
Odoo Companies in India – Driving Business Transformation.pdf
How AI/LLM recommend to you ? GDG meetup 16 Aug by Fariman Guliev

Dci in PHP

  • 3. Trygve Reenskaug James Coplien (Cope)
  • 5. playing roles not all behaviour at the same time
  • 7. This picture and on coming pages example from Victor Savkin: http://www.sitepoint.com/dci-the-evolution-of-the-object-oriented-paradigm/
  • 12. what the system is < > what the system does • anemic model, “data” • adding behaviour in a “context” • behaviour grouped in roles • context = use case, scenarios • model matches mental model • readability of object oriented code • object oriented < > class oriented
  • 14. “Wrapper” implementation • Instantiate the Roles and constructor-inject a RolePlayer- object in them. • Leads to “object schizophrenia”: what is the $this in a Role-method referring to? It should be the same object as the $this in the RolePlayer. https://en.wikipedia.org/wiki/Schizophrenia_%28object-oriented_programming%29 • Big NO-NO and showstopper in DCI.
  • 15. Some implementations of DCI in PHP that are none or less “wrapper”: • CoreDCI: can be used in PHP 5.3 (no traits). A method-injection PHP-implementa- tion from 2010 using naming conventions like r Rolename Actions-classes. Used in http://code.google.com/p/waxphp/. See http://code.google.com/p/php-coredci/wiki/UsingCoreDCI • Fatty: originally for Laravel. Uses closure object binding (in PHP 5.4). See http://kirkbushell.me/data-context-interaction-for-php/. Code on https://github.com/kirkbushell/fatty. • the “reverse wrapper” (object wraps the role rather than the role wrap- ping the object), which also results in methods of a role being injected in a data ob- ject (with examples in PHP 5.3 and using traits). See https://github.com/mbrowne/dci-php. Discussion: https://groups.google.com/d/msg/object-composition/YDKfrGuLXDo/ pRirNWtks4oJ
  • 16. CoreDCI: can be used in PHP 5.3 (no traits). A method-injection PHP-implemen- tation that gets the rolename for the objects from the context’s execute() signature. You need to implement an interface with the Rolename in the roleplaying object. That doesn’t make it very flexible if you want to add behaviour. Also: what is $this in Role methods? class Account extends DCIObject implements rMoneySource, rMoneySink { protected $balance; function __construct($initial_balance) { parent::__construct(); $this->balance = $initial_balance; } function Withdraw($amount) { if ($amount <= $this->balance) { $this->balance -= $amount; return $amount; } else throw new DCIException(“Insufficient Funds”,”Tried to withdraw $amount<br />{$this->balance} available.”); } function Deposit($amount) { $this->balance += $amount; } class TransferCtx extends Context { function Execute(rMoneySource $source, rMoneySink $sink, $amount) { parent::Execute(); $source->TransferFunds($sink,$amount); } } function GetBalance() { return $this->balance; } }
  • 17. Fatty: originally for Laravel. Uses closure object binding (in PHP 5.4). Example only shows how to use instead of inheritance. see: • http://php.net/manual/en/closure.bind.php#110845 for example adding method • https://gist.github.com/mbrowne/5047982 for a similar implementation Closure object binding: public function addMethod($methodName, $methodCallable) { if (!is_callable($methodCallable)) { throw new InvalidArgumentException(‘Second param must be callable’); } $this->methods[$methodName] = Closure::bind($methodCallable, $this, get_class()); } public function __call($methodName, array $args) { if (isset($this->methods[$methodName])) { return call_user_func_array($this->methods[$methodName], $args); } throw RunTimeException(‘There is no method with the given name to call’); }
  • 18. the “reverse wrapper” (object wraps the role rather than the role wrapping the object), which also results in methods of a role being injected in a data object. In each RolePlayer: function addRole($roleName, Context $context) { $this->_setCurrentContext($context); $roleClassName = $this->currentContextClassName.’Roles’.$roleName; if (!class_exists($roleClassName, false)) { throw new InvalidArgumentException(“The role ‘$roleClassName’ is not defined (it should be defined in the same *file* as the context to which it belongs).”);} $role = new $roleClassName($this, $context); $this->bindRoleMethods($role); return $this; } function __call($methodName, $args) { if (isset($this->roleMethods[$this->currentContextClassName][$methodName])) { $role = $this->roleMethods[$this->currentContextClassName][$methodName]; } if (!isset($role) || !method_exists($role, $methodName)) { // error handling... } //Call $role->$methodName() with the given arguments return call_user_func_array(array($role, $methodName), $args); }
  • 19. Mixins from Nooku Framework • Nooku Framework started as a new framework for Joomla. It had mixins before we had traits in PHP. • Mixins are methods mixed into an object (not into a class, like traits): $object->mixin($mixin); • DCI roles can be implemented as mixins. I made a mixout() method to get rid of the methods when leaving the context. • it is “under the hood” a kind of reverse wrapper: every object has a mixin()-method and when a method is called is is looked up in the list and then called on the mixin where it is defined. public function __call($method, $arguments) { if (isset($this->_mixed_methods[$method])) { //etc. $result = call_user_func_array(array($mixin, $method), $arguments); } ...
  • 20. Nooku’s __call() also looks at closures and other mixed-in methods. Here the part where the mixin is an object: elseif(is_object($this->_mixed_methods[$method])) { $mixin = $this->_mixed_methods[$method]; //Switch the mixin’s attached mixer $mixin->setMixer($this); // Call_user_func_array is ~3 times slower than direct method calls. I say: not worth that ugly switch switch (count($arguments)) { case 0 : $result = $mixin->$method(); break; case 1 : $result = $mixin->$method($arguments[0]); break; case 2 : $result = $mixin->$method($arguments[0], $arguments[1]); break; case 3 : $result = $mixin->$method($arguments[0], $arguments[1], $arguments[2]); break; default: // Resort to using call_user_func_array for many segments $result = call_user_func_array(array($mixin, $method), $arguments); }
  • 21. Work in progress... some thoughts: “Data” don’t exist • in Functional Programming • and Event Sourcing Data, state is • a left fold • a snapshot • a result of a stream of events
  • 22. • then what about DATA? - Context - Interaction • if we implement that with Event Sourcing • we have events as a result of interacting roles • a “context” instead of an “aggregate” • roles played by a reconstituted stream of events
  • 23. • can we learn from DCI for better Domain Driven Design? • behaviour related to use case / scenarios • adding behaviour at runtime (roles) • better names (context, role) • algorithm more a whole, readability • a model is not a tree...
  • 24. Take away: • separating behaviour from data Behaviour is better composable than objects