What is “loose coupling?” Please provide examples

2019-01-03 04:10发布

I can't seem to grok the concept of "loose coupling." I suppose it doesn't help that the word "loose" usually has a negative connotation, so I always forget that loose coupling is a good thing.

Will somebody please show some "before" and "after" code (or pseudocode) that illustrates this concept?

20条回答
forever°为你锁心
2楼-- · 2019-01-03 04:19

I propose a very simple Test of Code Coupling:

  1. Piece A of code is tightly coupled to Piece B of code if there exists any possible modification to the Piece B that would force changes in Piece A in order to keep correctness.

  2. Piece A of code is not tightly coupled to Piece B of code if there is no possible modification to the Piece B that would make a change to Piece A necessary.

This will help you to verify how much coupling there is between the pieces of your code. for reasoning on that see this blog post: http://marekdec.wordpress.com/2012/11/14/loose-coupling-tight-coupling-decoupling-what-is-that-all-about/

查看更多
姐就是有狂的资本
3楼-- · 2019-01-03 04:19

When you create an object of a class using new keyword in some other class, you are actually doing tight coupling (bad practice) instead you should use loose coupling which is a good practice

---A.java---

package interface_package.loose_coupling;

public class A {

void display(InterfaceClass obji)
{
    obji.display();
    System.out.println(obji.getVar());
}
}

---B.java---

package interface_package.loose_coupling;

public class B implements InterfaceClass{

private String var="variable Interface";

public String getVar() {
    return var;
}

public void setVar(String var) {
    this.var = var;
}

@Override
public void display() {
    // TODO Auto-generated method stub
    System.out.println("Display Method Called");
}
}

---InterfaceClass---

package interface_package.loose_coupling;

public interface InterfaceClass {

void display();
String getVar();
}

---MainClass---

package interface_package.loose_coupling;

public class MainClass {

public static void main(String[] args) {
    // TODO Auto-generated method stub

    A obja=new A();
    B objb=new B();
    obja.display(objb);     //Calling display of A class with object of B class 

}
}

Explanation:

In above example, we have two classes A and B

Class B implements Interface i.e. InterfaceClass.

InterfaceClass defines a Contract for B class as InterfaceClass have abstract methods of B class that can be access by any other class for example A.

In Class A we have display method which can except object of class which implements InterfaceClass (in our case it is B class). And on that object method of class A is calling display() and getVar() of class B

In MainClass we have created object of Class A and B. And calling display method of A by passing object of B class i.e. objb. Display method of A will be called with object of B class.

Now talking about loose coupling. Suppose in future you have to change the name of Class B to ABC then you do not have to change its name in display method of class B, just make the object of new (ABC class) and pass it to the display method in MailClass. You do not have to change anything in Class A

ref: http://p3lang.com/2013/06/loose-coupling-example-using-interface/

查看更多
家丑人穷心不美
4楼-- · 2019-01-03 04:20

I'll use Java as an example. Let's say we have a class that looks like this:

public class ABC
{
   public void doDiskAccess() {...}
}

When I call the class, I'll need to do something like this:

ABC abc = new ABC();

abc. doDiskAccess();

So far, so good. Now let's say I have another class that looks like this:

public class XYZ
{
   public void doNetworkAccess() {...}
}

It looks exactly the same as ABC, but let's say it works over the network instead of on disk. So now let's write a program like this:

if(config.isNetwork()) new XYZ().doNetworkAccess();
else new ABC().doDiskAccess();

That works, but it's a bit unwieldy. I could simplify this with an interface like this:

public interface Runnable
{
    public void run();
}

public class ABC implements Runnable
{
   public void run() {...}
}

public class XYZ implements Runnable
{
   public void run() {...}
}

Now my code can look like this:

Runnable obj = config.isNetwork() ? new XYZ() : new ABC();

obj.run();

See how much cleaner and simpler to understand that is? We've just understood the first basic tenet of loose coupling: abstraction. The key from here is to ensure that ABC and XYZ do not depend on any methods or variables of the classes that call them. That allows ABC and XYZ to be completely independent APIs. Or in other words, they are "decoupled" or "loosely coupled" from the parent classes.

But what if we need communication between the two? Well, then we can use further abstractions like an Event Model to ensure that the parent code never needs to couple with the APIs you have created.

查看更多
该账号已被封号
5楼-- · 2019-01-03 04:22

You can think of (tight or loose) coupling as being literally the amount of effort it would take you to separate a particular class from its reliance on another class. For example, if every method in your class had a little finally block at the bottom where you made a call to Log4Net to log something, then you would say your class was tightly coupled to Log4Net. If your class instead contained a private method named LogSomething which was the only place that called the Log4Net component (and the other methods all called LogSomething instead), then you would say your class was loosely coupled to Log4Net (because it wouldn't take much effort to pull Log4Net out and replace it with something else).

查看更多
Emotional °昔
6楼-- · 2019-01-03 04:22

It's a pretty general concept, so code examples are not going to give the whole picture.

One guy here at work said to me, "patterns are like fractals, you can see them when you zoom in really close, and when you zoom way out to the architecture level."

Reading the brief wikipedia page can give you a sense of this generalness:

http://en.wikipedia.org/wiki/Loose_coupling

As far as a specific code example...

Here's one loose coupling I've worked with recently, from the Microsoft.Practices.CompositeUI stuff.

    [ServiceDependency]
    public ICustomizableGridService CustomizableGridService
    {
        protected get { return _customizableGridService; }
        set { _customizableGridService = value; }
    }

This code is declaring that this class has a dependency on a CustomizableGridService. Instead of just directly referencing the exact implementation of the service, it simply states that it requires SOME implementation of that service. Then at runtime, the system resolves that dependency.

If that's not clear, you can read a more detailed explanation here:

http://en.wikipedia.org/wiki/Dependency_injection

Imagine that ABCCustomizableGridService is the imlpementation I intend to hook up here.

If I choose to, I can yank that out and replace it with XYZCustomizableGridService, or StubCustomizableGridService with no change at all to the class with this dependency.

If I had directly referenced ABCCustomizableGridService, then I would need to make changes to that/those reference/s in order to swap in another service implementation.

查看更多
叼着烟拽天下
7楼-- · 2019-01-03 04:23

Some long answers here. The principle is very simple though. I submit the opening statement from wikipedia:

"Loose coupling describes a resilient relationship between two or more systems or organizations with some kind of exchange relationship.

Each end of the transaction makes its requirements explicit and makes few assumptions about the other end."

查看更多
登录 后发表回答