[PHP] Fluent interfaces, de basis
Fluent interfaces
Inhoudsopgave
Inleiding
In diverse talen is het begrip 'Fluent interfaces' al reeds jaren een begrip. In PHP is het echter nog niet zo heel lang mogelijk deze techniek te gebruiken. Fluent interfaces biedt de mogelijkheid om meerdere methodes van een class aan elkaar te koppelen. Dit is echter pas mogelijk vanaf PHP 5. Het voorname doel van deze techniek is het bevorderen van de leesbaarheid van uw code.
Hieronder vindt u eerst een korte uitleg van Fluent interfaces. Daarna gaan we het wat uitgebreider behandelen.
top
Korte uitleg Fluent interfaces
Fluent interfaces biedt de mogelijkheid om meerdere methodes aan elkaar te 'koppelen'. Een kort voorbeeld vindt u hieronder.
Deze class is een hele simpele voorstelling welke gebruikt kan worden in bijvoorbeeld een webshop.
<?php
class order {
/**
* Database connection storage
* @var Object PDO instance
**/
private $db;
/**
* Last inserted order id
* @var Integer The last inserted order id
**/
private $iIdOrder;
/**
* Constructor will store the database connection
* @param Object Instance of PDO needed for database interaction
**/
public function __construct ( $dbConnection ) {
$this -> db = $dbConnection;
}
/**
* Add the order in the database
* @param String $sName The name of the customer
* @param String $sAddress The address of the customer
* @param String $sPlace The place of the customer
* @uses $this -> db Object Database instance
* @return $this Fluent interface
**/
public function addOrder ( $sName, $sAddress, $sPlace ) {
$this -> db -> query ( "INSERT INTO order (`name`, `address`, `place`) VALUES ('" .$sName. "','" .$sAddress. "','" .$sPlace. "') " );
$this -> iIdOrder = $this -> db -> lastInsertId ( );
return $this;
}
/**
* Add the item in the database
* @param $iProductNumber Integer The corresponding productnumber (usually a Foreign Key)
* @param $fAmount Float The amount to add
* @uses $this -> iIdOrder Integer The order defined with his key to add the products
* @return $this Fluent interface
**/
public function addItem ( $iProductNumber, $fAmount ) {
$this -> db -> query ( "INSERT INTO itemsOrder ( `idOrder`, `idProductNumber`, `amount` ) VALUES ( " .$this -> iIdOrder. ", " .$iProductNumber. ", " .$iAmount. " )" );
return $this;
}
}
$oOrder = new Order ( $db );
Een voorbeeld welke de techniek omschrijft:
<?php
$oOrder -> addOrder ( 'Marten van Urk', 'Straatnaam 22', 'Plaatsnaam' )
-> addItem ( 12, 3 )
-> addItem ( 124121, 1 )
-> addItem ( 122, 42 );
Zoals u ziet is het gebruiken van deze techniek geen hogere wiskunde. Echter moet u heel goed nadenken of u het gaat gebruiken en of u het kan gebruiken.
top
Uitgebreide uitleg Fluent interfaces
Zoals u in bovenstaand voorbeeld kan zien is het niets meer dan methods direct achter elkaar aanroepen. De gelegenheid moet zorgvuldig gekozen worden of u deze techniek kan gebruiken. De techniek bevat een tweetal handelingen. Waarvan een aanpassing in de method de belangrijkste is.
De method moet namelijk het object van zichzelf doorgeven. Zo kunt u direct de volgende method weer aanroepen.
Andi Gutmans schreef de volgende tekst over het gebruik van Fluent interfaces:
The million dollar question is when to actually use this kind of programming style. Of course there are no definitive answers but I suggest to consider the following points:
a) Use your intuition. If you don’t feel this will address the 95% of common use-case for using your interface, then it’s probably not the right solution for what you’re trying to accomplish.
b) As Paul noted, if in the common use-case you don’t have all the necessary data available to complete the task in one go, you should think twice about doing it.
c) Probably the most important point: It really has to read well in your language (e.g. English), preferably as a complete sentence. If you can’t read the code out aloud then it’s probably not what you want.
Wanneer we een iets uitgebreider voorbeeld bekijken zien we een andere kracht van Fluent interfaces:
<?php
class order {
/**
* Database connection storage
* @var Object PDO instance
**/
private $db;
/**
* Last inserted order id
* @var Integer The last inserted order id
**/
private $iIdOrder;
/**
* Constructor will store the database connection
* @param Object Instance of PDO needed for database interaction
**/
public function __construct ( $dbConnection ) {
$this -> db = $dbConnection;
}
/**
* Add the order in the database
* @param String $sName The name of the customer
* @param String $sAddress The address of the customer
* @param String $sPlace The place of the customer
* @uses $this -> db Object Database instance
* @return $this Fluent interface
**/
public function addOrder ( $sName, $sAddress, $sPlace ) {
$this -> db -> query ( "INSERT INTO order (`name`, `address`, `place`) VALUES ('" .$sName. "','" .$sAddress. "','" .$sPlace. "') " );
$this -> iIdOrder = $this -> db -> lastInsertId ( );
return $this;
}
/**
* Add the item in the database
* @param $iProductNumber Integer The corresponding productnumber (usually a Foreign Key)
* @param $fAmount Float The amount to add
* @uses $this -> iIdOrder Integer The order defined with his key to add the products
* @return $this Fluent interface
**/
public function addItem ( $iProductNumber, $fAmount ) {
$this -> db -> query ( "INSERT INTO itemsOrder ( `idOrder`, `idProductNumber`, `amount` ) VALUES ( " .$this -> iIdOrder. ", " .$iProductNumber. ", " .$iAmount. " )" );
return $this;
}
/**
* Decrease the amount in stock
* @param $iProductNumber Integer The corresponding productnumber (usually a Foreign Key)
* @uses $this -> db Object Database instance
* @return $this Fluent interface
**/
public function changeStock ( $iProductNumber ) {
$this -> db -> query ( "UPDATE stock SET amount = (amount - 1) WHERE idProductNumber = " . $iProductNumber );
}
/**
* Order elsewhere because it's not in our shop
* @param $iProductNumber Integer The corresponding productnumber (usually a Foreign Key)
* @return $this Fluent interface
**/
public function orderElsewhere ( $iProductNumber ) {
// Mail the other shop [....] or do something else
return $this;
}
}
$oOrder = new Order ( $db );
Een uitgebreider voorbeeld van Fluent interfaces:
<?php
$oOrder -> addOrder ( 'Marten van Urk', 'Straatnaam 22', 'Plaatsnaam' )
-> addItem ( 12, 3 ) -> changeStock ( 12 )
-> addItem ( 124121, 1 )
-> addItem ( 122, 42 ) -> orderElsewhere ( 122 );
Natuurlijk is het niet handig om van het de eerste product wel de voorraad aan te passen en van het tweede niet maar het gaat om het voorbeeld.
top
Vragen en/of opmerkingen
De techniek zelf is niet echt de moeilijkheidsgraad. Echter de keuze of u het gaat gebruiken is iets wat vele grote namen in ons wereldje bezig houdt. Wanneer je nog vragen en / of opmerkingen hebt kunt u deze altijd plaatsen.
top
|