Proxy
Assez proche de l'Adapteur, le Proxy cherche à ajouter un niveau de
redirection entre l'appel d'une méthode d'un objet et l'action associée. A cet effet, on
construit une nouvelle classe implémentant l'interface de l'objet à manipuler et
déportant toutes les actions sur un autre objet implémentant la même interface.
Ce type de structure vise à pouvoir changer l'objet cible sans changer l'objet
source (manipulé).
Exemple :
/** Interface représentant un espace de dessin */
public interface Canvas {
/** Ajout d'un objet graphique */
public void addGraphicElement( GraphicElement ge );
}
/** Proxy pour l'espace de dessin */
public class CanvasProxy implements Canvas {
private Canvas c;
public CanvasProxy( Canvas c ) {
this.c = c;
}
public void addGraphicElement( GraphicElement ge ) {
[Link]( ge );
}
}
Dans cet exemple, une interface Canvas est définie avec une méthode pour
ajouter des objets graphiques. Le proxy CanvasProxy est une classe qui se charge
d'implémenter l'interface Canvas et d'appeler les méthodes sur l'objet Canvas passé
en paramètre de constructeur. On pourrait comme exemple pratique, imaginer que le
canvas puisse aussi exister dans sa forme contraire pour faire office de gomme. En
passant dans le mode "gomme", tout objet ajouté effacerait une partie du fond
comme une empreinte, pour cela, il sufferait dans la classe CanvasProxy de modifier
ou changer d'objet Canvas. L'exploitant manipulerait dans tous les cas le même
objet.
Les Proxy sont trés utilisés pour la gestion d'objets distribués (protocole RMI
en Java par exemple). L'idée étant de construire des Proxy capable de communiquer
avec des objets distants (usage de la sérialisation en Java) sans que l'exploitant
fasse de différences entre un accès locale ou un accès distant.
Exemple en PHP
<?php
class ProxyBookList {
private $bookList = NULL;
//bookList is not instantiated at construct time
function __construct() {
}
function getBookCount() {
if (NULL == $this->bookList) {
$this->makeBookList();
}
return $this->bookList->getBookCount();
}
function addBook($book) {
if (NULL == $this->bookList) {
$this->makeBookList();
}
return $this->bookList->addBook($book);
}
function getBook($bookNum) {
if (NULL == $this->bookList) {
$this->makeBookList();
}
return $this->bookList->getBook($bookNum);
}
function removeBook($book) {
if (NULL == $this->bookList) {
$this->makeBookList();
}
return $this->bookList->removeBook($book);
}
//Create
function makeBookList() {
$this->bookList = new bookList();
}
}
class BookList {
private $books = array();
private $bookCount = 0;
public function __construct() {
}
public function getBookCount() {
return $this->bookCount;
}
private function setBookCount($newCount) {
$this->bookCount = $newCount;
}
public function getBook($bookNumberToGet) {
if ( (is_numeric($bookNumberToGet)) && ($bookNumberToGet <= $this-
>getBookCount())) {
return $this->books[$bookNumberToGet];
} else {
return NULL;
}
}
public function addBook(Book $book_in) {
$this->setBookCount($this->getBookCount() + 1);
$this->books[$this->getBookCount()] = $book_in;
return $this->getBookCount();
}
public function removeBook(Book $book_in) {
$counter = 0;
while (++$counter <= $this->getBookCount()) {
if ($book_in->getAuthorAndTitle() == $this->books[$counter]-
>getAuthorAndTitle()) {
for ($x = $counter; $x < $this->getBookCount(); $x++) {
$this->books[$x] = $this->books[$x + 1];
}
$this->setBookCount($this->getBookCount() - 1);
}
}
return $this->getBookCount();
}
}
class Book {
private $author;
private $title;
function __construct($title_in, $author_in) {
$this->author = $author_in;
$this->title = $title_in;
}
function getAuthor() {
return $this->author;
}
function getTitle() {
return $this->title;
}
function getAuthorAndTitle() {
return $this->getTitle().' by '.$this->getAuthor();
}
}
function writeln($line_in) {
echo $line_in."<br/>";
}
writeln( 'BEGIN TESTING PROXY PATTERN');
writeln('');
$proxyBookList = new ProxyBookList();
$inBook = new Book('PHP for Cats','Larry Truett');
$proxyBookList->addBook($inBook);
writeln('test 1 - show the book count after a book is added');
writeln($proxyBookList->getBookCount());
writeln('');
writeln('test 2 - show the book');
$outBook = $proxyBookList->getBook(1);
writeln($outBook->getAuthorAndTitle());
writeln('');
$proxyBookList->removeBook($outBook);
writeln('test 3 - show the book count after a book is removed');
writeln($proxyBookList->getBookCount());
writeln('');
writeln('END TESTING PROXY PATTERN');
?>