Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.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
Oop “什么是”呢;松耦合?“;请举例说明_Oop_Language Agnostic_Loose Coupling - Fatal编程技术网

Oop “什么是”呢;松耦合?“;请举例说明

Oop “什么是”呢;松耦合?“;请举例说明,oop,language-agnostic,loose-coupling,Oop,Language Agnostic,Loose Coupling,我似乎无法理解“松耦合”的概念。我想“松耦合”这个词通常有负面含义是没有帮助的,所以我总是忘记松耦合是一件好事 请有人出示一些“之前”和“之后”代码(或伪代码)来说明这个概念吗?定义 本质上,耦合是一个给定对象或一组对象在多大程度上依赖于另一个对象或另一组对象来完成其任务 高耦合 想想一辆车。为了使发动机起动,必须将钥匙插入点火开关,转动,必须有汽油,必须有火花,活塞必须点火,发动机必须启动。你可以说汽车发动机与其他几个物体高度耦合。这是高度耦合,但这并不是一件坏事 松耦合 设想一个网页的用户控

我似乎无法理解“松耦合”的概念。我想“松耦合”这个词通常有负面含义是没有帮助的,所以我总是忘记松耦合是一件好事

请有人出示一些“之前”和“之后”代码(或伪代码)来说明这个概念吗?

定义 本质上,耦合是一个给定对象或一组对象在多大程度上依赖于另一个对象或另一组对象来完成其任务

高耦合 想想一辆车。为了使发动机起动,必须将钥匙插入点火开关,转动,必须有汽油,必须有火花,活塞必须点火,发动机必须启动。你可以说汽车发动机与其他几个物体高度耦合。这是高度耦合,但这并不是一件坏事

松耦合
设想一个网页的用户控件,它负责允许用户发布、编辑和查看某些类型的信息。单个控件可用于让用户发布新信息或编辑新信息。控件应该能够在两个不同的路径(新建和编辑)之间共享。如果控件的编写方式需要来自包含它的页面的某种类型的数据,那么可以说它的耦合度太高。控件不需要容器页面中的任何内容。

松耦合通常是两个参与者在同一工作负载上独立工作。因此,如果有两个web服务器使用相同的后端数据库,那么可以说这些web服务器是松散耦合的。紧密耦合的例子是在一台web服务器上有两个处理器。。。这些处理器是紧密耦合的

希望这会有所帮助。

抱歉,但“松耦合”不是编码问题,而是设计问题。“松散耦合”一词与理想的“高内聚”状态密切相关,是对立的,但又是互补的

松散耦合仅仅意味着应构造单个设计元素,以减少它们需要了解的有关其他设计元素的不必要信息量

高内聚性有点像“紧密耦合”,但高内聚性是一种状态,在这种状态下,真正需要了解彼此的设计元素被设计为干净优雅地协同工作

关键是,一些设计元素应该知道其他设计元素的细节,所以它们应该以这种方式设计,而不是意外地。其他设计元素不应该知道其他设计元素的细节,因此它们应该以这种方式设计,有目的地设计,而不是随机设计


实现这一点留给读者作为练习:)。

紧密耦合的代码依赖于具体的实现。如果我在代码中需要一个字符串列表,并且我这样声明它(在Java中)

ArrayList myList=new ArrayList();
然后我依赖于ArrayList实现

如果我想将其更改为松散耦合的代码,我会将引用设置为接口(或其他抽象)类型

List myList=new ArrayList();
这使我无法调用特定于ArrayList实现的
myList
上的任何方法。我仅限于列表界面中定义的那些方法。如果我后来决定我真的需要一个LinkedList,我只需要在创建新列表的一个地方更改代码,而不需要在调用ArrayList方法的100个地方更改代码


当然,您可以使用第一个声明实例化ArrayList,并限制自己不使用任何不属于List接口的方法,但使用第二个声明可以让编译器保持诚实。

您可以阅读有关的通用概念的更多信息


简而言之,它描述了两个类之间的关系,其中每个类对另一个类的了解最少,并且每个类都可以继续正常工作,无论另一个类是否存在,并且不依赖于另一个类的特定实现。

我将以Java为例。假设我们有这样一个类:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
当我给班级打电话时,我需要做如下事情:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
到目前为止,一切顺利。现在让我们假设我有另一个类,看起来像这样:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
它看起来与ABC完全相同,但假设它通过网络而不是磁盘工作。现在让我们编写一个如下的程序:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
这是可行的,但有点笨拙。我可以用这样的界面来简化这个过程:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
现在,我的代码可以如下所示:

public class ABC
{
   public void doDiskAccess() {...}
}
ABC abc = new ABC();

abc. doDiskAccess();
public class XYZ
{
   public void doNetworkAccess() {...}
}
if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();
public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}
Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();
看看这是多么干净和简单的理解?我们刚刚理解了松耦合的第一个基本原则:抽象。这里的关键是确保ABC和XYZ不依赖于调用它们的类的任何方法或变量。这使得ABC和XYZ成为完全独立的API。或者换句话说,它们与父类“解耦”或“松散耦合”

但是如果我们需要两者之间的沟通呢?那么,我们可以使用进一步的抽象,例如,确保父代码永远不需要与您创建的API耦合。

您可以将(紧耦合或松耦合)看作是将特定类与其对另一个类的依赖分离所需的工作量。例如,如果类中的每个方法在底部都有一个finally块,在该块中您调用Log4Net来记录一些内容,那么您会说您的类与Log4Net紧密耦合。如果您的类包含一个名为LogSomething的私有方法,它是唯一调用Log4Net组件的地方(其他方法都称为LogSomething),那么您会说您的类与Log4Net松散耦合(因为将Log4Net拉出并用其他方法替换它不会花费太多精力)