3: Tercer Patrón de diseño - FranzBurneo/Patrones-de-dise-o GitHub Wiki
Estrategia pertenece a los patrones de diseño de comportamiento, este patrón permite definir una familia de algoritmos, pone a cada uno de ellos en una clase separada y hacer que sus objetos sean intercambiables.
Una de las estrategias dominantes de los diseños orientados a objetos es el principio "open-close" La figura muestra cómo se logra de forma rutinaria: encapsular los detalles de la interfaz en una clase base y enterrar los detalles de la implementación en las clases derivadas. Los clientes pueden entonces acoplarse a una interfaz y no tener que experimentar el transtorno asociado con el cambio: ningún impacto cuando cambia el número de clases derivadas y ningún impacto cuando cambia la implementación de una clase derivada.
Los clientes deberían preferir el "nivel adicional de direccionamiento indirecto" que ofrece una interfaz (o una clase base abstracta). La interfaz captura la abstracción (es decir, la "ficción útil") que el cliente desea ejercer, y las implementaciones de esa interfaz están efectivamente ocultas.
La entidad de interfaz podría representar una clase base abstracta o las expectativas de firma del método por parte del cliente. En el primer caso, la jerarquía de herencia representa un polimorfismo dinámico. En el último caso, la entidad Interfaz representa el código de plantilla en el cliente y la jerarquía de herencia representa el polimorfismo estático.
En este ejemplo tenemos modos de transporte hacia un aeropuerto es un ejemplo de patrón Estrategia. Existen varias opciones, como conducir el propio automóvil, tomar un taxi, un servicio de transporte al aeropuerto, un autobús urbano o un servicio de limusina. Para algunos aeropuertos, el metro y los helicópteros también están disponibles como medio de transporte al aeropuerto. Cualquiera de estos modos de transporte llevará al viajero al aeropuerto, y se pueden usar indistintamente. El viajero debe elegir la estrategia en función de las compensaciones entre costo, conveniencia y tiempo.
En el Patrón de estrategia, un contexto elegirá la extensión concreta apropiada de una interfaz de clase.
En este ejemplo, la StrategyContextclase fijará una estrategia de StrategyCaps, StrategyExclaimo StrategyStarsen función de un parámetro StrategyContext recibe en instanciación. Cuando el método showName() es llamado en StrategyContextlo llamará al método showName() en la estrategia que se establece.
<?php
class StrategyContext {
private $strategy = NULL;
//bookList is not instantiated at construct time
public function __construct($strategy_ind_id) {
switch ($strategy_ind_id) {
case "C":
$this->strategy = new StrategyCaps();
break;
case "E":
$this->strategy = new StrategyExclaim();
break;
case "S":
$this->strategy = new StrategyStars();
break;
}
}
public function showBookTitle($book) {
return $this->strategy->showTitle($book);
}
}
interface StrategyInterface {
public function showTitle($book_in);
}
class StrategyCaps implements StrategyInterface {
public function showTitle($book_in) {
$title = $book_in->getTitle();
$this->titleCount++;
return strtoupper ($title);
}
}
class StrategyExclaim implements StrategyInterface {
public function showTitle($book_in) {
$title = $book_in->getTitle();
$this->titleCount++;
return Str_replace(' ','!',$title);
}
}
class StrategyStars implements StrategyInterface {
public function showTitle($book_in) {
$title = $book_in->getTitle();
$this->titleCount++;
return Str_replace(' ','*',$title);
}
}
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();
}
}
writeln('BEGIN TESTING STRATEGY PATTERN');
writeln('');
$book = new Book('PHP for Cats','Larry Truett');
$strategyContextC = new StrategyContext('C');
$strategyContextE = new StrategyContext('E');
$strategyContextS = new StrategyContext('S');
writeln('test 1 - show name context C');
writeln($strategyContextC->showBookTitle($book));
writeln('');
writeln('test 2 - show name context E');
writeln($strategyContextE->showBookTitle($book));
writeln('');
writeln('test 3 - show name context S');
writeln($strategyContextS->showBookTitle($book));
writeln('');
writeln('END TESTING STRATEGY PATTERN');
function writeln($line_in) {
echo $line_in."<br/>";
}
?>
BEGIN TESTING STRATEGY PATTERN
test 1 - show name context C
PHP FOR CATS
test 2 - show name context E
PHP!for!Cats
test 3 - show name context S
PHP*for*Cats
END TESTING STRATEGY PATTERN