松散耦合本质上是模块之间如何发展的间接依赖。
通常,当存在紧密耦合的系统时,不同的模块/对象具有非常特殊的行为,这些行为假定外围对象的行为。这样的对象链接/耦合到其他模块行为,并且不能孤立地或在任何其他上下文中重复使用它们。
即使负责单个功能的此类模块也无法独立发展或无法发展
一个例子:
假设您有3个对象
Shape
(一个模型对象)和Canvas
(一个UI元素)。现在
假定方法shape.draw(Canvas)
将在画布平面提供的平面上绘制对象。
现在,有时窗户会被部分遮盖并调整大小。在这种情况下,上面的方法可能只是这样做。
shape::draw(Canvas) {
Rect.WindowLeft = Canvas.GetWindowRect.getLeftOffset();
Rect.LeftPixel = Canvas.GetWindowRect.pixels() + Rect.WindowLeft;
.... // like this get all co-ordinates.
draw_instance(Rect); // This will draw the actual shape.
}
基本上,这里的draw函数拾取需要绘制事物的矩形。这很容易理解(人们可能将其称为简单)代码。但是,这是极其耦合的代码。
想象一下情况:
- 如果画布的固定窗口机制不再是矩形怎么办?
- 如果Canvas保留私有的其他偏移量怎么办?
- 如果某些其他应用程序想要相同的形状但不再具有GUI窗口(例如,它正在创建图像并保存在文件中)怎么办。
问题的根源在于,对象shape
知道并因此紧密耦合用Canvas
。
理想的是给像素集写形状。对shape
像素实际写入的位置不应有(甚至是隐式的)知识。