[MVC] Ajouter des fonctionnalités au modèle
Bonjour,
Dans mon framework PHP, je dispose d'une classe Model simple, qui sert de base à tous mes modèles :
Code:
1 2 3 4 5 6 7 8 9 10 11
| abstract class Model {
public function save() {
/* Sauvegarde les données en base */
}
public function delete() {
/* Supprime les données en base */
}
} |
Je voudrais ajouter des fonctionnalités à mes modèles, de manière optionnelle et en réutilisant mon code.
Mon idée est d'utiliser le pattern Decorator.
Je définis une classe Decorator abstraite :
Code:
1 2 3 4 5 6 7 8 9 10 11
| abstract class Decorator {
$protected $model;
public function __construct( $model ) {
$this->model = $model;
}
public function __call( $method, $args ) {
return call_user_func_array( array( get_class( $this->model ), $method), $args );
}
} |
J'aurais par exemple un Decorator permettant de gérer un modèle multilingue, en ajoutant simplement un suffixe (_en, _fr) aux noms des champs.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class TranslateDecorator extends Decorator {
public $language;
public $translated;
public function __construct() {
parent::__construct();
if ( !empty( $_SESSION['language'] ) ) {
$this->language = $_SESSION['language'];
}
}
public function __set( $name, $value ) {
if ( in_array( $name, $this->translated ) ) {
$name .= '_' . $this->language;
}
$this->model->name = $value;
}
} |
Ou Decorator permettant de gérer une corbeille :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| class TrashDecorator extends Decorator {
/* Surcharge de delete() */
public function delete() {
$this->model->is_deleted = 1;
$this->model->save();
}
public function unDelete() {
$this->model->is_deleted = 0;
$this->model->save();
}
public function emptyTrash() {
foreach ( $this->model->findAll() as $model ) {
$model->delete();
}
}
} |
Je définis mes modèles :
Code:
1 2 3
| class ArticleModel extends Model {
// Définition de la classe
} |
Ensuite je peux instancier mon modèle et ajouter mes decorators :
Code:
1 2 3 4 5 6 7 8 9 10
| $article = new TrashDecorator( new TranslateDecorator( new ArticleModel ) );
$article->translated = array( 'title', 'text' );
$article->language = 'fr';
$article = $article->findOne( 4 );
$article->title = 'Mon titre';
$article->save();
$article->delete();
$article->emptyTrash(); |
Je trouve ce système efficace, simple et élégant.
Que pensez-vous de cette approche ?