Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何使用接口实现松耦合?_Php_Oop_Design Patterns_Architecture - Fatal编程技术网

Php 如何使用接口实现松耦合?

Php 如何使用接口实现松耦合?,php,oop,design-patterns,architecture,Php,Oop,Design Patterns,Architecture,我似乎没有掌握接口如何实现松耦合的概念?你可能会发现这个问题与其他问题重复,但我已经阅读了许多与这个主题相关的答案,我还没有找到令人满意的解释 下面是有多少开发人员实现松耦合的示例 interface shape { public function sayName(); } class Circle implements shape { public function sayName(){ echo 'Hello my name is circle';

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

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

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”类,因此创建了紧密耦合

为了解决这个问题,我们可以这样做

界面形状{ 公共函数sayName(); }

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

我的问题是,如果我可以在没有接口的情况下实现松耦合,为什么要使用接口?在上述场景中,该接口将提供哪些好处?或者,如果在上面的示例中不使用接口,我将面临哪些问题


谢谢你的帮助

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

我倾向于将接口视为定义/强制执行合同的便捷方式。代替每个形状都能表示hello的简单示例,考虑一个需要将每个形状呈现给图像的情况。

这段伪代码显示了如何处理没有接口的正方形和圆形

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()
}
在某些情况下,如果您只关心渲染形状的能力,则可以针对该接口编程

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
}
你可以有这样的东西:

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

现在,您可以确保
rendershape
函数对圆或正方形实现的任何特定细节都不可见。它需要知道的是,您可以调用
render

,每次需要三角形、梯形或五边形等新形状时,您都必须通过您的方法重写Creator constructor()方法代码。。。。松散耦合意味着不必重写创建者代码,只需创建一个实现Shape@MarkBaker你错了。我将有一个创造者,我可以有成千上万的客户。重写一个创建者还是一千个客户端更好?@JayBhatt这毫无意义。接口与您在creator类中试图完成的任务无关。您正在尝试开发一个将字符串值映射到类实现的系统。接口唯一需要做的是,结果类应该实现接口。这是一种简化的服务定位策略,但我认为它的可扩展性不足以处理1000种类型,而不会造成维护的噩梦。其他实现使用某种配置文件将字符串映射到类实现。关键的一点是,创建者应该实现所需的接口。