接口如何用于松散耦合



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

下面是一个示例,说明有多少开发人员实现了松耦合。

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"one_answers"Square"类,从而创建紧密耦合。

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

界面形状{公共函数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();

这个例子修复了前面例子的问题,但我们根本不使用接口。

我的问题是,如果我可以在没有接口的情况下实现松耦合,为什么要使用接口?在上述情况下,接口会带来什么好处?或者,如果我不在上面的例子中使用接口,我会面临什么问题?

谢谢你的帮助。

正如其他人所指出的,您所做的更多的是依赖注入,这是一个相关但独立于松散耦合的主题。我将尝试通过接口深入了解松耦合的简单应用程序。

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

这个伪代码显示了如何在没有接口的情况下处理方形和圆形。

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
}

相反,如果我们说我们不太关心类型的形状是什么,而只关心你可以渲染它,我们最终会得到以下界面:

interface renderableShape {
  function render()
}

在只关心渲染形状的能力的情况下,可以针对该接口对进行编程。

你可以有这样的东西:

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

现在,您要确保renderShapes函数无法查看Circle或Square实现的任何特定细节。它只需要知道您可以调用render

最新更新