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

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

问题描述

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

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.

你可以有这样的东西:

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天全站免登陆