Haciendo del Desarrollo y la Arquitectura Web, ciencia y pasión.

Open Close Principle, OCP

Lo que nos dice este principio es que "las entidades de software (clases o funciones…) deben estar abiertas para extenderse, pero cerradas para modificación". Esto no es mas que una planificacion correcta del flujo de vida de una entidad.

Acotando en la medida de lo posible el continuo remendado de dicha entidad dejando solo la posibilidad de actualizar o extender.

Nuestro objetivo es dejar la clase inalterada y dejar solo la puerta abierta a la posibilidad de añadir nuevo comportamiento. Para poder llevar a cabo esto es imprescindible tener un conocimiento de la aplicacion y de su alcance profundo, aunque esto no siempre es posible. Veamos un ejemplo sencillo que nos hará rapidamente violar el principio Abierto-Cerrado.

Nuestra clase escribe un mensaje sencillo por pantalla:

class SaySomething{
function hello() {
echo "Hello, Dan!\n";
}
}

Ahora supongamos que seria interesante que que el metodo hello pudiera pasar parametros para hacer personalizable el mensaje

class SaySomething{
function hello($subject) {
echo "Hello, $subject!\n";
}
}

Estupendo, y si posteriormente quisieramos hacerlo aun mas flexible introduciendo un mensaje cambiante?

class SaySomething{
function hello($message, $subject) {
echo "$message, $subject!\n";
}
}

Cada vez que la naturaleza del mensaje cambie, nos veriamos obligados a cambiar nuestra clase. Una nueva especificacion nos solicita que el mensaje pueda ser de tipo array o un String. Diseñamos nuestra clase para que sea extendible ampliando su comportamiento sin tocar una linea de esta:

class SaySomething{
private $message;

function __construct (Message $message){
$this->message = $message;
}

function hello($subject) {
$this->message->echoMessage($subject);
}
}

abstract class Message{
private $content;
abstract function echoMessage($subject);
}

class StringMessage extends Message{
function __construct ($content){
$this->content = $content;
}

public function echoMessage($subject){
echo "$this->content $subject";
}
}

class ArrayMessage extends Message{
function __construct ($content){
$this->content = $content;
}

public function echoMessage($subject){
echo print_r ($this->content, true);
}
}

$s = new SaySomething(new StringMessage ("Hola Que tal"));
$s->hello("Dani");