php - 接口(interface)如何用于松散耦合?

标签 php oop design-patterns architecture

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

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

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();

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

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

界面形状{ 公共(public)功能说名();

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();

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

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

感谢您的帮助。

最佳答案

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

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

此伪代码展示了如何在没有界面的情况下处理正方形和圆形。

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()
}

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

你可以有这样的东西:

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

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

关于php - 接口(interface)如何用于松散耦合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17929197/

相关文章:

php - 如何通过 SIP 发送即时消息

PHP 提取分隔符之间的字符串允许重复

java - 一个对象引用一个类 A 的对象,而另一个类 B 的对象作为其实例变量,是否也指向类型 B 的对象?

c++ - 抽象工厂的多重继承

java - 单例中的双重检查锁定

javascript - Axios 发布为 JSON 对象,如何更改

php - 使用 jquery 解析 json 不起作用

java - 在java oop中创建多个对象

Python3 : access a dunder variable

c# - 在这种情况下应该使用什么设计模式?