Jon*_*han 321
紧耦合是指一组类高度依赖彼此的情况.
当一个类承担太多责任,或者当一个问题分散在许多类而不是拥有自己的类时,就会出现这种情况.
通过促进单一责任和关注点分离的设计实现松耦合.
松散耦合的类可以独立于其他(具体)类来使用和测试.
接口是用于解耦的强大工具.类可以通过接口而不是其他具体类进行通信,只需通过实现接口,任何类都可以在该通信的另一端.
紧耦合的例子:
class CustomerRepository
{
private readonly Database database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
class Database
{
public void AddRow(string Table, string Value)
{
}
}
Run Code Online (Sandbox Code Playgroud)
松耦合示例:
class CustomerRepository
{
private readonly IDatabase database;
public CustomerRepository(IDatabase database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
interface IDatabase
{
void AddRow(string Table, string Value);
}
class Database : IDatabase
{
public void AddRow(string Table, string Value)
{
}
}
Run Code Online (Sandbox Code Playgroud)
另一个例子在这里.
BKS*_*eon 157
帽子与身体"松散耦合".这意味着您可以轻松取下帽子,而无需对人/身体进行任何更改.当你可以做到这一点,那么你有"松耦合".请参阅下面的详细说明.
想想你的皮肤.它贴在你的身上.它像手套一样适合.但是如果你想改变肤色从白色到黑色怎么办?你能想象剥掉你的皮肤,染上它然后把它贴回去等会有多痛苦吗?改变你的皮肤是很困难的,因为它与你的身体紧密相连.你不能轻易做出改变.你必须从根本上重新设计一个人,以使这成为可能.
上帝不是一个好的面向对象的程序员.
现在想想早上穿衣服.你不喜欢蓝色吗?没问题:你可以换上红色衬衫.你可以轻松,轻松地做到这一点,因为衬衫并没有像你的皮肤一样真正地连接到你的身体.衬衫不知道或不关心它正在发生什么样的身体.换句话说,你可以换衣服,而不用改变你的身体.
简而言之,这就是基本概念.
这很重要,因为软件一直在变化.一般来说,您希望能够轻松修改代码.
简而言之,松散耦合使代码更容易更改.上面的答案提供了一些值得阅读的代码.
图片归因.
Don*_*kby 69
在面向对象的设计中,耦合量是指一个类的设计取决于另一个类的设计.换句话说,A类的变化多长时间与B类的变化相关?紧耦合意味着两个类通常一起变化,松散耦合意味着它们大多是独立的.通常,建议使用松耦合,因为它更容易测试和维护.
您可能会发现Martin Fowler撰写的这篇论文(PDF)很有帮助.
Jom*_*rge 14
一般情况下,Tight Coupling很糟糕,但大部分时间都是如此,因为它降低了代码的灵活性和可重用性,使得更改变得更加困难,阻碍了可测试性等.
紧密耦合对象是一个需要彼此了解很多的对象,并且通常高度依赖于彼此的接口.在紧密耦合的应用程序中更改一个对象通常需要更改许多其他对象.在小型应用程序中,我们可以轻松识别更改,并且错过任何内容的机会较少.但是在大型应用程序中,每个程序员并不总是知道这些相互依赖关系,或者有机会错过更改.但是每组松散耦合的对象都不依赖于其他对象.
简而言之,我们可以说松散耦合是一个设计目标,旨在减少系统组件之间的相互依赖性,目的是降低一个组件中的更改需要更改任何其他组件的风险.松散耦合是一个更通用的概念,旨在提高系统的灵活性,使其更易于维护,并使整个框架更"稳定".
耦合指的是一个元素与另一个元素的直接知识的程度.我们可以说例如:A和B,只有当A改变其行为时,B才会改变它的行为.松散耦合的系统可以很容易地分解成可定义的元素.
小智 10
紧耦合意味着一个类依赖于另一个类。
松耦合意味着一个类依赖于接口而不是类。
在紧耦合中,方法中声明了硬编码的依赖项。
在松散耦合中,我们必须在运行时从外部传递依赖而不是硬编码。(松散耦合系统使用接口来减少对类的依赖。)
例如,我们有一个系统可以以两种或多种方式发送输出,如 JSON 输出、CSV 输出等。
public interface OutputGenerator {
public void generateOutput();
}
public class CSVOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("CSV Output Generator");
}
}
public class JSONOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("JSON Output Generator");
}
}
// In Other Code, we write Output Generator like...
public class Class1 {
public void generateOutput() {
// Here Output will be in CSV-Format, because of hard-coded code.
// This method tightly coupled with CSVOutputGenerator class, if we want another Output, we must change this method.
// Any method, that calls Class1's generateOutput will return CSVOutput, because Class1 is tight couple with CSVOutputGenerator.
OutputGenerator outputGenerator = new CSVOutputGenerator();
output.generateOutput();
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,如果我们想改变 JSON 中的输出,那么我们需要在整个代码中查找和改变,因为 Class1 与 CSVOutputGenerator 类紧密耦合。
public interface OutputGenerator {
public void generateOutput();
}
public class CSVOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("CSV Output Generator");
}
}
public class JSONOutputGenerator implements OutputGenerator {
public void generateOutput() {
System.out.println("JSON Output Generator");
}
}
// In Other Code, we write Output Generator like...
public class Class1 {
public void generateOutput(OutputGenerator outputGenerator) {
// if you want to write JSON, pass object of JSONOutputGenerator (Dependency will be passed externally to this method)
// if you want to write CSV, pass object of CSVOutputGenerator (Dependency will be passed externally to this method)
// Due to loose couple with class, we don't need to change code of Class1, because Class1 is loose coupled with CSVOutputGenerator or JSONOutputGenerator class
// Any method, that calls Class1's generateOutput will desired output, because Class1 does not tight couple with CSVOutputGenerator or JSONOutputGenerator class
OutputGenerator outputGenerator = outputGenerator;
output.generateOutput();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
我理解的是,与松耦合架构相比,紧耦合架构不能提供很大的变更灵活性.
但是在松散耦合的体系结构的情况下,消息格式或操作平台或改进业务逻辑不会影响另一端.如果系统被拆除进行改造,当然另一端将无法访问服务一段时间,但除此之外,未改变的一端可以恢复与改造之前的消息交换.
小智 5
我关于耦合的博客文章的摘录:
什么是紧耦合:
如上定义,紧密耦合对象是需要了解其他对象的对象,通常高度依赖于彼此的接口。
当我们在紧密耦合的应用程序中更改一个对象时,通常需要更改许多其他对象。在小型应用程序中没有问题,我们可以轻松识别更改。但是,在大型应用程序中,并非每个消费者或其他开发人员都总是知道这些相互依存关系,否则将来更改的可能性很大。
让我们以购物车演示代码来了解紧密耦合:
namespace DNSLooseCoupling
{
public class ShoppingCart
{
public float Price;
public int Quantity;
public float GetRowItemTotal()
{
return Price * Quantity;
}
}
public class ShoppingCartContents
{
public ShoppingCart[] items;
public float GetCartItemsTotal()
{
float cartTotal = 0;
foreach (ShoppingCart item in items)
{
cartTotal += item.GetRowItemTotal();
}
return cartTotal;
}
}
public class Order
{
private ShoppingCartContents cart;
private float salesTax;
public Order(ShoppingCartContents cart, float salesTax)
{
this.cart = cart;
this.salesTax = salesTax;
}
public float OrderTotal()
{
return cart.GetCartItemsTotal() * (2.0f + salesTax);
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的例子有问题
紧密耦合会产生一些困难。
在这里,OrderTotal()
方法为我们提供了购物车中当前物品的完整金额。如果我们要在此购物车系统中添加折扣功能。在上面的代码中很难做到这一点,因为我们必须在每个类上进行更改,因为它们之间紧密耦合。
这里使用类比有很多很好的答案,但工作中的一个朋友给了我一个例子,我比这里提到的所有那些都更喜欢......眼睛和眼镜!
紧耦合
紧耦合将是眼睛。如果我想修复我的视力,我进行眼部移植手术并不昂贵,而且风险相当大。但是,如果设计师(作为人类)找到了更好的方法呢?添加与主体松散耦合的功能,以便轻松更改!(是的……眼镜)
松耦合
我可以轻松更换眼镜而不会破坏我的基本视力。我可以摘下眼镜,我的视力会和以前一样(不会更好或更糟)。使用不同的眼镜改变了我们通过眼睛看世界的方式,风险很小,易于维护。
概括
所以下次有人问你“谁在乎我的代码是否紧密耦合?” 答案是关于改变的努力、维持的努力和改变的风险。
那么这是如何在 C# 中完成的呢?接口和依赖注入!
编辑
这也是装饰者模式的一个很好的例子,其中眼睛是我们通过满足界面要求但提供不同功能(例如太阳镜、老花镜、珠宝商放大镜等)来装饰的类