Merida Design Blog

Publicado el | Artículos / , ,

S.O.L.I.D. Principios de programación orientada a objetos: Segregación de interfaz

Este principio establece que:

Un cliente nunca deber ser obligado a implementar una interfaz que no usa o forzado a depender de métodos que no emplea.

En el artículo anterior comenzamos a trabajar con formas sólidas y cálculo de volumen por lo que podemos agregar un contrato mas a la interfaz ShapeInterface que implementan estas formas.


    interface ShapeInterface {
      public function area();
      public function volume();
    }

Con el código anterior las formas que creemos ahora, tendrán que implementar el método volume, pero tenemos formas como el Square(cuadrado) que es una forma plana y la estamos forzando a implementar un método que no va a usar y el principio de segregación va en contra de esto.

En lugar de la solución anterior podemos crear otra interfaz llamada SolidShapeInterface que contenga el método volume para que las formas sólidas como cubos puedan implementar haciendo uso de ésta interfaz.


    interface ShapeInterface {
      public function area();
    }
    
    interface SolidShapeInterface {
      public function volume();
    }
    
    class Cuboid implements ShapeInterface, SolidShapeInterface {
      public function area() { ... }
      
      public function volume() { ... }
    }

Este enfoque es mucho mejor que el anterior, sin embargo aún tiene un problema, ahora cada vez que operemos con los objetos tipo forma tendremos que validar que tipo de interfaz implementa para saber que método llamar.

Para resolver esto podemos crear una nueva interfaz que nos sirva para unificar ambas interfaces en una sola api.


    interface ManageShapeInterface {
      public function calculate();
    }
    
    class Square implements ShapeInterface, ManageShapeInterface {
      public function area() { ... }
      
      public function calculate() {
        return $this->area();
      }
    }
    
    class Cuboid implements ShapeInterface, SolidShapeInterface, ManageShapeInterface {
      public function area() { ... }
      
      public function volume() { ... }
      
      public function calculate() {
        return $this->area() + $this->volume();
      } 
    }

Ahora en la clase AreaCalculator podemos reemplazar la llamada al método area por calculate y verificar que el objeto sea una instancia de la interfaz ManageShapeInterface en lugar de ShapeInterface.


    class AreaCalculator() {
      ...
      
      public function sum() {
        foreach($this->shapes as $shape) {
          if(is_a($shape, 'ManageShapeInterface')) {
            $area[] = $shape->calculate();
            continue; 
          }
          
          throw new AreaCalculatorInvalidShapeException;
        }
        
        return array_sum($area);
      }
    }

 

Conclusión

Programando de esta forma es posible implementar funcionalidad en los módulos a medida que se vaya necesitando sin necesidad de estar obligados a implementar métodos que el módulo nunca va a usar.

En el siguiente y último artículo de la serie veremos el Principio de Inversión de Dependencias.



Publicaciones que pueden interesarte

    Deja un comentario

      tope
    Derechos Reservados, Merida Design 2017
    %d bloggers like this: