在面向对象范式中,有人能准确地描述松耦合和紧耦合之间的区别吗?
当前回答
如果一个对象的创建/存在依赖于另一个不能被剪裁的对象,它的紧密耦合。如果依赖关系可以被裁剪,那么它的松散耦合。考虑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在公认答案中的评论有一个很好的解释。
其他回答
在面向对象设计中,耦合量指的是一个类的设计依赖于另一个类的设计的程度。换句话说,A类力的变化与B类力的变化相关的频率是多少?紧耦合意味着两个类经常一起更改,松耦合意味着它们大部分是独立的。一般来说,推荐使用松耦合,因为它更容易测试和维护。
你可能会发现Martin Fowler的这篇论文(PDF)很有帮助。
紧密耦合是指一组类彼此高度依赖。
当一个类承担了太多的责任,或者当一个关注点分散到许多类而不是拥有自己的类时,就会出现这种情况。
松耦合是通过促进单一责任和关注点分离的设计实现的。
松耦合类可以独立于其他(具体的)类使用和测试。
接口是用于解耦的强大工具。类可以通过接口而不是其他具体类进行通信,并且任何类都可以通过实现接口而处于通信的另一端。
紧密耦合的例子:
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)
{
}
}
松耦合的例子:
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 implements IDatabase
{
public void AddRow(string Table, string Value)
{
}
}
另一个例子。
如果一个对象的创建/存在依赖于另一个不能被剪裁的对象,它的紧密耦合。如果依赖关系可以被裁剪,那么它的松散耦合。考虑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移动通信
松耦合和紧耦合是关于程序组件之间的依赖关系。这意味着不仅依赖于编程类,还依赖于编程系统组件。
例如,如果你只使用简单的原始SQL查询从SQL Server接收数据,这是松耦合。与松耦合和简单原始SQL查询相反的是紧耦合和实体框架核心。在实体框架核心,你必须完整的模型与POCO类在你的代码反映数据库结构,这意味着任何变化在数据库中,你必须反映在代码。
因此,程序代码和数据库结构之间的紧密耦合是实体框架,这种方法的对立面是拒绝使用任何ORM,并拒绝在程序代码中使用完整的镜像数据库结构。