接口如何用于松耦合?

时间:2013-07-29 16:25:08

标签: php oop design-patterns architecture

我似乎没有掌握接口如何实现松散耦合的概念?您可能会发现此问题与其他问题重复,但我已阅读了许多与此主题相关的答案,但我没有找到令人满意的解释。

以下是有多少开发人员实现松散耦合的示例。

interface shape {
   public function sayName();
}

class Circle implements shape {

     public function sayName(){
          echo 'Hello my name is circle';
      }
}

class Square implements shape {

     public function sayName(){
          echo 'Hello my name is square';
      }
}

class Creator {
       public $shape = null;
       public function __construct(Shape $shape){
          $this->shape = $shape;
       }
}

$circle = new Creator(new Circle());
$circle->sayName();

$square = new Creator(new Square());
$square->sayName();

在上面的例子中,我们使用接口的多态来实现松散耦合。但我没有看到这段代码松散耦合。在上面的例子中,调用代码(客户端)使用“new”操作符直接引用“Circle”和“Square”类,从而创建紧密耦合。

要解决这个问题,我们可以做这样的事情。

界面形状{        public function sayName();     }

class Circle implements shape {

     public function sayName(){
          echo 'Hello my name is circle';
      }
}

class Square implements shape {

     public function sayName(){
          echo 'Hello my name is square';
      }
}

class Creator {
       public $shape = null;
       public function __construct($type){
          if(strtolower($type) == 'circle'){
             $this->shape = new Circle();
          } else if(strtolower($type) == 'square'){
             $this->shape = new Square();
          } else {
             throw new Exception('Sorry we don\'t have '.$type.' shape');
          }
       }
}

$circle = new Creator('Circle');
$circle->sayName();

$square = new Creator('Square');
$square->sayName();

此示例修复了上一个示例的问题,但我们根本不使用接口。

我的问题是,如果我可以在没有它的情况下实现松散耦合,为什么我应该使用接口?接口在上述场景中提供了哪些好处?如果我在上面的例子中没有使用界面,我会遇到什么问题?

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

正如其他人已经注意到的那样,你所做的更多的是依赖注入,这是一个相关的,但与松散耦合不同的主题。我将尝试通过接口给出松散耦合的简单应用。

我倾向于将接口视为定义/执行合同的便捷方式。而不是每个形状都可以打招呼的简单示例,考虑一个需要将每个形状渲染为图像的情况。

此伪代码显示了如何处理没有界面的正方形和圆形。

class Circle {
  function renderCircle() { ... }
}

class Square {
  function renderSquare() { ... }
}

// then when we use them
Circle[] circlesArray = loadCircles
Square[] squaresArray = loadSquares

foreach(circle in circlesArray){
  circle.renderCircle
}

foreach(square in squaresArray){
  square.renderSquare
}

如果相反,我们说我们并不关心它的 type 形状,但只有你可以渲染它,我们最终会得到以下界面:

interface renderableShape {
  function render()
}

在您只关心呈现形状的能力的情况下,您可以该接口进行编程。

你可以这样:

function renderShapes(Array[renderableShape] shapes){
  foreach(shape in shapes){
    shape.render()
  }
}

您现在确保您的renderShapes功能无法查看Circle或Square实施的任何具体细节。需要知道的是,您可以拨打render