接口如何用于松耦合? [英] how interfaces are used for loose coupling?

查看:173
本文介绍了接口如何用于松耦合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I don't seem to grasp the concept of how interfaces will implement loose coupling? You might find this question to be a duplicate of some other question but I've read many answers related to this topic and I haven't found a satisfactory explanation.

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

Below is an example of how many developers implement loose coupling.

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"类,因此产生了紧密的耦合.

In the above example we are using polymorphism of interface to achieve loose coupling. But I don't see that this code is loosely coupled. In the above example the calling code (client) is directly referring to "Circle" and "Square" classes using "new" operator hence creating tight coupling.

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

To solve this problem we can do something like this.

界面形状{ 公共功能sayName(); }

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

此示例解决了上一个示例的问题,但是我们根本不使用接口.

This example fixes the problems of previous example but we don't use interface at all.

我的问题是,如果没有接口就可以实现松散耦合,为什么还要使用接口?在上述情况下,该界面将提供什么好处?还是如果在上面的示例中不使用界面,我会遇到什么问题?

My question is why should I use interface if I can implement loose coupling without it? what benefits would the interface offer in the above scenario? or what problems would I face if I don't use interface in the above example?

感谢您的帮助.

推荐答案

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

As others have noted, what you're doing is more along the lines of dependency injection, which is a related, but separate topic from loose coupling. I'll try to give some insight into the simple application of loose coupling via interfaces.

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

I tend to think of interfaces as a handy way of defining/enforcing contracts. Instead of the simplistic example in which every shape can say hello, consider a case where you need to render each shape to an image.

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

This pseudo-code shows how you might deal with Squares and Circles with no 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
}

如果相反,我们说我们不太关心形状的类型,但是只有您可以渲染它,我们才能得到以下界面:

If instead, we say that we don't so much care about what type of shape it is, but only that you can render it, we end up with the following interface:

interface renderableShape {
  function render()
}

在仅关注渲染形状功能的情况下,您可以针对该界面进行 编程.

And so on cases where you are only concerned about the ability to render the shape, you program against that interface.

您可能会遇到这样的事情:

You could have something like this:

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

现在,您要确保您的renderShapes函数不了解Circle或Square实现的任何特定细节.它所需要知道的就是您可以致电render.

You're now ensuring that your renderShapes function has no visibility into any of the specific details of the Circle or Square implementations. All it needs to know is that you can call render.

这篇关于接口如何用于松耦合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆