Pattern Factory : Ou comment faire tout en 1 ligne
Vous révez de ça :
<?php
$service = new MonService()
-> setConfig(...)
-> setAdapter(...)
-> setModel(...)
-> process();
...
Vous révez de ça :
<?php
$service = new MonService()
-> setConfig(...)
-> setAdapter(...)
-> setModel(...)
-> process();
Mais ce n'est pas possible en PHP et vous avez l'erreur suivante (ligne 4 = ligne du setConfig() ) :
PHP Parse error: syntax error, unexpected T_OBJECT_OPERATOR in <votre-fichier-ici> on line 4
Du coup, désespérement vous devez faire :
$service = new MonService();
$service
-> setConfig(...)
-> setAdapter(...)
-> setModel(...)
-> process();
Imaginez d'autre part, qu'à plusieurs endroits dans votre application vous utilisez systématiquement toujours la même classe, avec des instances différentes, mais qu'à chaque fois vous deviez reconfigurer l'objet de la même manière en faisant par exemple :
$service1 = new MailService(); $service1->setOutgoingAdapter(new SendmailAdapter()); $service1->setIncomingAdapter(new PostfixAdapter()); ... $service1->send(...); ... ... $service2 = new MailService(); $service2->setOutgoingAdapter(new SendmailAdapter()); $service2->setIncomingAdapter(new PostfixAdapter()); ... $service2->send(...);
A chaque fois que vous désirez instancier votre MailService, vous avez le droit d'écrire 3 lignes de code...
Le pattern Factory peut alors vous aidez. Vous pourriez définir un "paramétrage" par défaut de votre service qui soit déjà tout préconfiguré :
class MailService {
...
public final static function factory($type='default') {
$service = new MailService();
switch($type) {
case 'default':
$service->setOutgoingAdapter(new SendmailAdapter());
$service->setIncomingAdapter(new PostfixAdapter());
break;
case 'mock':
$service->setOutgoingAdapter(new MockOutgoingAdapter());
$service->setIncomingAdapter(new MockIncomingAdapter());
break;
default:
throw new RuntimeException("Unknown factory type '$type'");
}
return $service;
}
}
Vous pourrez maintenant appeler votre service en une seule ligne de code :
$result = MailService::factory('default')->send(...);
Pensez à factoriser votre code !
Commentaires
C'est typiquement le genre de syntaxe dont on est très friand dans Copix :-)
Il faut avouer que cela simplifie l'écriture.... par contre on se retrouve vite avec des syntaxes compact dont il faut connaître la signification :-)
_dao ('MaTable')->findBy (
_daoSp ()->addCondition ('champ', '=', $valeur)
->addCondition ('champ2', '=', $valeur2)
->orderBy ('champ3')
)
Ce qui ici signifie : Je vais récupérer dans ma table "MaTable", grâce à un "Data Access Object", les enregistrement qui correspondent aux paramètres de recherches (daoSP = Data Access Object Search Params) ....
Le plus proche de l'exemple serait la fabrique de classe, utilisée de la sorte :
_class ('classId')
...qui retourne un new 'ClassId' (en plus d'inclure le fichier en question grâce à un système d'autoload).
J'aime assez aussi la possibilité de faire un raccourcis pour obtenir des singletons de ces objets, avec par exemple
_ioClass ('classId');// (instance of class) qui retournera systématiquement la même instance de la classe 'classId'.
En tout cas c'est sûr, le nested call de PHP 5 est pour moi une grande nouveauté par rapport à la version 4 :-)
Merci beaucoup pour ce petit billet très instructif ;)
Mais comment n'y ai je pas pensé avant ?