问题
Can any one describe the exact difference between loose coupling and tight coupling in Object oriented paradigm?
回答1:
Tight coupling is when a group of classes are highly dependent on one another.
This scenario arises when a class assumes too many responsibilities, or when one concern is spread over many classes rather than having its own class.
Loose coupling is achieved by means of a design that promotes single-responsibility and separation of concerns.
A loosely-coupled class can be consumed and tested independently of other (concrete) classes.
Interfaces are a powerful tool to use for decoupling. Classes can communicate through interfaces rather than other concrete classes, and any class can be on the other end of that communication simply by implementing the interface.
Example of tight coupling:
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)
{
}
}
Example of loose coupling:
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)
{
}
}
Another example here.
回答2:
Explanation without ANY code
Summary Example:
The Hat is "loosely coupled" to the body. This means you can easily take the hat off without making any changes to the person/body. When you can do that then you have "loose coupling". See below for elaboration.
Tight coupling (Detailed Example)
Think of your skin. It's stuck to your body. It fits like a glove. But what if you wanted to change your skin colour from say white to black? Can you imagine just how painful it would be to peel off your skin, dye it, and then to paste it back on etc? Changing your skin is difficult because it is tightly coupled to your body. You just can't make changes easily. You would have to fundamentally redesign a human being in order to make this possible.
- Key Point #1: In other words, if you want to change the skin, you would also HAVE TO change the design of your body as well because the two are joined together - they are tightly coupled.
God was not a good object oriented programmer.
Loose coupling (Detailed Example)
Now think of getting dressed in the morning. You don't like blue? No problems: you can put a red shirt on instead. You can do this easily and effortlessly because the shirt is not really connected to your body the same way as your skin. The shirt doesn't know or care about what body it is going on. In other words, you can change your clothes, without really changing your body.
- That's key point #2. If you change your shirt, then you are not forced to change your body - when you can do that, then you have loose coupling. When you can't do that, then you have tight coupling.
That's the basic concept in a nutshell.
Why is all of this important?
It's important because software changes all the time. Generally speaking you want to be able to easily modify your code, without changing your code. I know that sounds like an oxymoron, but please bear with me.
Practical Examples of Coupling in When Coding
CSV/JSON/DB Examples: If somebody wants their output in a CSV file rather than JSON etc., or if you want to switch from MySQL to PostGreSQL you should be able to make those changes extremely easily in your code, without having to rewrite the entire class etc. In other words, you do not want to tightly couple your application with a specific database implementation (e.g. Mysql) or to a particular output (e.g. CSV files). Because, as is inevitable in software, changes will come. When they do come, it's much easier if your parts of your code are loosely coupled.
Car Parts Example: If somebody wants their car in black, you shouldn't have to redesign the entire car in order to do that. A car and its spare parts would be a perfect example of a loosely coupled architecture. If you want to replace your engine with a better one, you should be able to simply remove your engine without too much effort and swap it for a better one. If your car only works with Rolls Royce 1234 Engines and no other engines - then your car will is tightly coupled to that engine (Rolls Royce 1234). It would be better if you changed the design of your car so that it will work with any engine, so that it is a bit more loosely coupled with it's components. Even better would be if your car could work without needing an engine at all! Some amount of coupling is going to happen, but you should work to minimise it as much as you can. Why? Because when requirements change we should still be able to deliver good quality software, very quickly and we are aided in that goal by loose coupling.
Summary
In short, loose coupling makes code easier to change. The answers above provide some code which is worth reading at this point.
Polymorphism and SOLID Principles
Re: @TimoHuovinen comments - the concept of loose coupling goes hand-in-hand with the concepts of polymorphism. If you grasp the basic analogy of a shirt/car parts, then you will be ready to make sense of polymorphism. The best way, at this point is to read the code samples provided by my estimable colleagues in the other answers on this thread. If I say anymore you might get overloaded with too much info.
Picture Attribution.
回答3:
In object oriented design, the amount of coupling refers to how much the design of one class depends on the design of another class. In other words, how often do changes in class A force related changes in class B? Tight coupling means the two classes often change together, loose coupling means they are mostly independent. In general, loose coupling is recommended because it's easier to test and maintain.
You may find this paper by Martin Fowler (PDF) helpful.
回答4:
In general Tight Coupling is bad in but most of the time, because it reduces flexibility and re-usability of code, it makes changes much more difficult, it impedes testability etc.
Tightly Coupled Object is an object need to know quite a bit about each other and are usually highly dependent on each other interfaces. Changing one object in a tightly coupled application often requires changes to a number of other objects, In small application we can easily identify the changes and there is less chance to miss anything. But in large applications these inter-dependencies are not always known by every programmer or chance is there to miss changes. But each set of loosely coupled objects are not dependent on others.
In short we can say, loose coupling is a design goal that seeks to reduce the interdependencies between components of a system with the goal of reducing the risk that changes in one component will require changes in any other component. Loose coupling is a much more generic concept intended to increase the flexibility of a system, make it more maintainable, and make the entire framework more 'stable'.
Coupling refers to the degree of direct knowledge that one element has of another. we can say an eg: A and B, only B change its behavior only when A change its behavior. A loosely coupled system can be easily broken down into definable elements.
回答5:
When two objects are loosely coupled, they can interact but have very little knowledge of each other.
Loosely coupled designs allow us to build flexible OO systems that can handle change.
Observer design pattern is a good example for making classes loosely coupled, you can have a look on it in Wikipedia.
回答6:
The way I understand it is, that tightly coupled architecture does not provide a lot of flexibility for change when compared to loosely coupled architecture.
But in case of loosely coupled architectures, message formats or operating platforms or revamping the business logic does not impact the other end. If the system is taken down for a revamp, of course the other end will not be able to access the service for a while but other than that, the unchanged end can resume message exchange as it was before the revamp.
回答7:
An extract from my blog post on coupling:
What is Tight Coupling:-
As par above definition a Tightly Coupled Object is an object that needs to know about other objects and are usually highly dependent on each other's interfaces.
When we change one object in a tightly coupled application often it requires changes to a number of other objects. There is no problem in a small application we can easily identify the change. But in the case of a large applications these inter-dependencies are not always known by every consumer or other developers or there is many chance of future changes.
Let’s take a shopping cart demo code to understand the tight coupling:
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);
}
}
}
Problems with the above example
Tight Coupling creates some difficulties.
Here, OrderTotal()
methods is give us complete amount for the current items of the carts. If we want to add the discount features in this cart system. It is very hard to do in above code because we have to make changes at every class as it is very tightly coupled.
回答8:
Tight Coupling means one class is dependent on another class.
Loose Coupling means one class is dependent on interface rather than class.
In tight coupling, there are hard-coded dependency declared in methods.
In loose coupling, we must pass dependency externally at runtime instead of hard-coded. (Loose couple systems use interface for decreased dependency with class.)
For example, we have a system that can send output in two or more ways like JSON output, CSV output, etc.
Tight Coupled
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();
}
}
In the example above, if we want to change the output in JSON, then we need to find and change in the whole code, because Class1 is tightly coupled with the CSVOutputGenerator class.
Loose Coupled
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();
}
}
回答9:
There are certain tools that provide dependency injection through their library, for example in .net we have ninject Library .
If you are going further in java then spring provides this capabilities.
Loosly coupled objects can be made by introducing Interfaces in your code, thats what these sources do.
Say in your code you are writing
Myclass m = new Myclass();
now this statement in your method says that you are dependent on myclass
this is called a tightly coupled. Now you provide some constructor injection , or property injection and instantiating object then it will become loosly coupled.
回答10:
Loose coupling means that the degree of dependency between two components is very low.
Example: GSM SIM
Tight coupling means that the degree of dependency between two components is very high.
Example: CDMA Mobile
回答11:
Loose coupling is and answer to to old style hardcoded dependencies and related issues issues like frequent recompilation when anything changes and code reuse. It stresses on implementing the worker logic in components and avoiding solution specific wire up code there.
Loose Coupling = IoC See this for easier explanation.
回答12:
Loose Coupling is the process of giving the dependency your class needs indirectly without providing all the information of the dependency(i.e in the from of interface) in case tight coupling you directly give in the dependency which is not good way of coding.
回答13:
It's about classes dependency rate to another ones which is so low in loosely coupled and so high in tightly coupled. To be clear in the service orientation architecture, services are loosely coupled to each other against monolithic which classes dependency to each other is on purpose
回答14:
If an object's creation/existence dependents on another object which can't be tailored, its tight coupling. And, if the dependency can be tailored, its loose coupling. Consider an example in Java:
class Car {
private Engine engine = new Engine( "X_COMPANY" ); // this car is being created with "X_COMPANY" engine
// Other parts
public Car() {
// implemenation
}
}
The client of Car
class can create one with ONLY "X_COMPANY" engine.
Consider breaking this coupling with ability to change that:
class Car {
private Engine engine;
// Other members
public Car( Engine engine ) { // this car can be created with any Engine type
this.engine = engine;
}
}
Now, a Car
is not dependent on an engine of "X_COMPANY" as it can be created with types.
A Java specific note: using Java interfaces just for de-coupling sake is not a proper desing approach. In Java, an interface has a purpose - to act as a contract which intrisically provides de-coupling behavior/advantage.
Bill Rosmus's comment in accepted answer has a good explanation.
回答15:
There is a lot of nice answers here using analogies but a friend at work gave me an example that I liked more than all of the ones mentioned here... Eyes and Glasses!
Tight Coupling
Tight coupling would be the eyes. If I want to fix my vision, I'ts very expensive to get an eye transplant and holds a fair amount of risk. But what if the designer (being the human race) found a better way. Add a feature that is loosely coupled to the body so it can be easily changed! (yes.. glasses)
Loose coupling
I can easily replace my glasses without breaking my underlying vision. I can take off the glasses and my vision will be how it was before (not better or worse). Using different pairs of glasses changes how we see the world through our eyes with little risk and easy maintainability.
Summary
So next time someone asks you "who cares if my code is tightly-coupled?" The answer is all about effort to change, effort to maintain and risk of change.
So how is this done in C#? Interfaces and Dependency Injection!
EDIT
This a good example of the Decorator pattern as well, where the the eyes are the class we are decorating by meeting interface requirements but giving different functionality (e.g. sunglasses, reading glasses, magnifying glasses for jewelers e.t.c)
来源:https://stackoverflow.com/questions/2832017/what-is-the-difference-between-loose-coupling-and-tight-coupling-in-the-object-o