在面向对象范式中,有人能准确地描述松耦合和紧耦合之间的区别吗?


当前回答

无代码说明

用简单的类比来解释概念。代码可以稍后再写。

松耦合的例子:

在上图中,帽子与身体“松散耦合”。这意味着你可以很容易地摘下帽子,而不需要对人/身体做任何改变。当你能做到这一点时,你就有了“松耦合”。详情见下文。

详细的例子

想想你的皮肤。它粘在你身上了。它非常合适。但是如果你想把你的肤色从白色变成黑色呢?你能想象剥掉你的皮肤,染色,然后再贴回去有多痛苦吗?改变你的皮肤是困难的,因为它与你的身体紧密相连。你只是不能轻易做出改变。为了使这成为可能,你必须从根本上重新设计一个人。

关键点#1:换句话说,如果你想改变皮肤,你也必须改变你身体的设计,因为两者是连接在一起的——它们是紧密耦合的。

上帝不是一个优秀的面向对象程序员。

松耦合(详细示例)

现在想想早上穿衣服。你不喜欢蓝色?没问题:你可以换一件红衬衫。你可以轻松轻松地做到这一点,因为衬衫并不像皮肤那样真正地连接在你的身体上。衬衫不知道也不关心它穿在什么身体上。换句话说,你可以改变你的衣服,而不需要真正改变你的身体。

这是第二点。如果你换了衬衫,那么你就不会被迫改变你的身体——当你可以这样做时,你就有了松耦合。当你不能这样做时,你就有了紧密耦合。

这是一个简单的基本概念。

为什么所有这些都很重要?

在编写软件时,更改是不可避免的。如果我们提前知道变更将发生在某个特定的地方,那么我们应该确保我们的软件在那个特定的点上是松散耦合的,因为这将使我们能够轻松快速地进行这些更改,而没有错误.....这意味着什么呢?看一些例子:

软件中的松耦合:

CSV/JSON示例:在我职业生涯的早期,我的经理说:“给我一个CSV文件的输出”。太好了。我开始努力,创造了一个像魔法一样有效的日常工作。一两周后,他说:“实际上,我想为另一个客户端提供JSON格式的输出。”

真痛苦。我不得不重写整个剧本。我有点知道会发生这种情况,所以我用接口重写了整个程序——一种松散耦合的设计模式,现在,添加了新的输出格式,进行更改就容易多了。我可以编辑JSON部分,而不用担心我会破坏我的CSV输出。

另外重要的一点是:软件的变化是正常的。在变化点上松散耦合。

DB Examples: if you want to switch from sqlLite to PostGreSQL easily - loosely coupled code makes it really easy to switch (i.e. to put on a red shirt instead of a blue shirt). The Rails ActiveRecord library is loosely coupled on its database implementation. This makes it super easy for someone to use their own database implementation, while using the same code base! Cloud Provider examples: Or if you're using AWS and they start charging too much because of market dominance, you should be able to somewhat easily switch to Google or Azure etc. This is precisely the reason why libraries like Active Storage exist - they provide users with a healthy indifference as to the specific cloud provider being used (Azure, AWS S3, GCS etc.). You can easily change cloud providers with just a one-line code change. The implementation details of the cloud storage providers are loosely coupled. Testing: if you want to test your software, with predetermined outputs and inputs - how are you going to do it? With loosely coupled software - it's a breeze: you can run your tests, and you can also deploy your production code and do it all in the same code base. With tightly coupled code, testing your production code is nearly impossible.

我们是否需要让所有内容都“松散耦合”?可能不会。我们必须运用我们的判断力。一定程度的耦合是不可避免的。但是如果你提前知道它会在哪里发生变化,就考虑最小化它。我还建议不要猜测事情会在哪里发生变化,不要将所有事情松散耦合。松散的情侣,只在你需要的时候。

总结

简而言之,松耦合使代码更容易更改。

上面的答案提供了一些值得一读的代码。

高级的主题

松耦合与多态性和接口密切相关。如果你喜欢漫画和类比,看看我写过的其他文章:

什么是多态性? 什么是接口? 你说的“漏洞百出的抽象”是什么意思——不是我写的。

归因。

其他回答

当两个对象松散耦合时,它们可以相互作用,但知之甚少 对方。

松散耦合设计允许我们构建能够处理变更的灵活的OO系统。

观察者设计模式是一个让类松散耦合的好例子,你可以在维基百科上看到它。

无代码说明

用简单的类比来解释概念。代码可以稍后再写。

松耦合的例子:

在上图中,帽子与身体“松散耦合”。这意味着你可以很容易地摘下帽子,而不需要对人/身体做任何改变。当你能做到这一点时,你就有了“松耦合”。详情见下文。

详细的例子

想想你的皮肤。它粘在你身上了。它非常合适。但是如果你想把你的肤色从白色变成黑色呢?你能想象剥掉你的皮肤,染色,然后再贴回去有多痛苦吗?改变你的皮肤是困难的,因为它与你的身体紧密相连。你只是不能轻易做出改变。为了使这成为可能,你必须从根本上重新设计一个人。

关键点#1:换句话说,如果你想改变皮肤,你也必须改变你身体的设计,因为两者是连接在一起的——它们是紧密耦合的。

上帝不是一个优秀的面向对象程序员。

松耦合(详细示例)

现在想想早上穿衣服。你不喜欢蓝色?没问题:你可以换一件红衬衫。你可以轻松轻松地做到这一点,因为衬衫并不像皮肤那样真正地连接在你的身体上。衬衫不知道也不关心它穿在什么身体上。换句话说,你可以改变你的衣服,而不需要真正改变你的身体。

这是第二点。如果你换了衬衫,那么你就不会被迫改变你的身体——当你可以这样做时,你就有了松耦合。当你不能这样做时,你就有了紧密耦合。

这是一个简单的基本概念。

为什么所有这些都很重要?

在编写软件时,更改是不可避免的。如果我们提前知道变更将发生在某个特定的地方,那么我们应该确保我们的软件在那个特定的点上是松散耦合的,因为这将使我们能够轻松快速地进行这些更改,而没有错误.....这意味着什么呢?看一些例子:

软件中的松耦合:

CSV/JSON示例:在我职业生涯的早期,我的经理说:“给我一个CSV文件的输出”。太好了。我开始努力,创造了一个像魔法一样有效的日常工作。一两周后,他说:“实际上,我想为另一个客户端提供JSON格式的输出。”

真痛苦。我不得不重写整个剧本。我有点知道会发生这种情况,所以我用接口重写了整个程序——一种松散耦合的设计模式,现在,添加了新的输出格式,进行更改就容易多了。我可以编辑JSON部分,而不用担心我会破坏我的CSV输出。

另外重要的一点是:软件的变化是正常的。在变化点上松散耦合。

DB Examples: if you want to switch from sqlLite to PostGreSQL easily - loosely coupled code makes it really easy to switch (i.e. to put on a red shirt instead of a blue shirt). The Rails ActiveRecord library is loosely coupled on its database implementation. This makes it super easy for someone to use their own database implementation, while using the same code base! Cloud Provider examples: Or if you're using AWS and they start charging too much because of market dominance, you should be able to somewhat easily switch to Google or Azure etc. This is precisely the reason why libraries like Active Storage exist - they provide users with a healthy indifference as to the specific cloud provider being used (Azure, AWS S3, GCS etc.). You can easily change cloud providers with just a one-line code change. The implementation details of the cloud storage providers are loosely coupled. Testing: if you want to test your software, with predetermined outputs and inputs - how are you going to do it? With loosely coupled software - it's a breeze: you can run your tests, and you can also deploy your production code and do it all in the same code base. With tightly coupled code, testing your production code is nearly impossible.

我们是否需要让所有内容都“松散耦合”?可能不会。我们必须运用我们的判断力。一定程度的耦合是不可避免的。但是如果你提前知道它会在哪里发生变化,就考虑最小化它。我还建议不要猜测事情会在哪里发生变化,不要将所有事情松散耦合。松散的情侣,只在你需要的时候。

总结

简而言之,松耦合使代码更容易更改。

上面的答案提供了一些值得一读的代码。

高级的主题

松耦合与多态性和接口密切相关。如果你喜欢漫画和类比,看看我写过的其他文章:

什么是多态性? 什么是接口? 你说的“漏洞百出的抽象”是什么意思——不是我写的。

归因。

松耦合和紧耦合是关于程序组件之间的依赖关系。这意味着不仅依赖于编程类,还依赖于编程系统组件。

例如,如果你只使用简单的原始SQL查询从SQL Server接收数据,这是松耦合。与松耦合和简单原始SQL查询相反的是紧耦合和实体框架核心。在实体框架核心,你必须完整的模型与POCO类在你的代码反映数据库结构,这意味着任何变化在数据库中,你必须反映在代码。

因此,程序代码和数据库结构之间的紧密耦合是实体框架,这种方法的对立面是拒绝使用任何ORM,并拒绝在程序代码中使用完整的镜像数据库结构。

如果一个对象的创建/存在依赖于另一个不能被剪裁的对象,它的紧密耦合。如果依赖关系可以被裁剪,那么它的松散耦合。考虑Java中的一个例子:

class Car {

    private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine
    // Other parts

    public Car() { 
        // implemenation 
    }

}

Car类的客户端只能创建一个“X_COMPANY”引擎。

考虑打破这种耦合的能力来改变它:

class Car {

    private Engine engine;
    // Other members

    public Car( Engine engine ) { // this car can be created with any Engine type
        this.engine = engine;
    }

}

现在,Car不依赖于“X_COMPANY”的引擎,因为它可以用类型创建。

Java特有的注意事项:仅仅为了解耦合而使用Java接口并不是一种合适的设计方法。在Java中,接口有一个目的——充当契约,从本质上提供解耦合行为/优势。

Bill Rosmus在公认答案中的评论有一个很好的解释。

松耦合意味着两个组件之间的依赖程度非常低。 示例:GSM SIM卡

紧密耦合意味着两个组件之间的依赖程度非常高。 例如:CDMA移动通信