解耦的理解

什么是耦合

耦合,指的是两个可以协作的部件的关系。A和B可以协作,则A和B的关系是耦合。

为什么要解耦

如果A可以和O,P,Q,S…(简称集合F)协作,则A就和集合F发生了耦合,如果A发生了变化,想要维持系统正常,那么集合F就需要顺应A的变化而变化,以保持协作有效。同样的,集合F中的任何一个发生了变化,A也需要发生变化(至少是局部的变化),以保持协作有效。

如何解耦

1. 使用类的向上转型或接口回调的方式进行解耦
public interface IBase{
        void say();
    }

    public class A implements IBase{
        @Override
        public void say() {
            System.out.println("I am A");
        }
    }

    public class B implements IBase{
        @Override
        public void say() {
            System.out.println("I am B");
        }
    }

    public class C{
        public void put(IBase base){
            base.say();
        }
    }

同理,可以使用继承方式,但是接口由于继承。根据具体的业务逻辑选择合适的方式。

2. 利用适配器模式进行解耦
  • 提供一套它制定的协议给A和集合F,让A和F都按B的安排来工作。(例如"USB数据线",它告诉手机怎么传输数据,同时告诉电脑怎么接收数据,手机和电脑按照"USB数据线"的安排来工作;例如RabbitMQ)
    这种工作方式,本质上是将A与F的耦合,拆成了 A与协议B的耦合 + F与协议B的耦合。也就是将"部件和部件"的耦合拆为了"部件和协议"的耦合
  • 作为话事人,分别适配集合F的每一个元素。(例如翻译软件,可以将所有语言翻译为中文;例如JVM)
    这种工作方式,本质上是将A与F的耦合,拆成了 A与B的耦合 + F与B的耦合。本质上还是"部件和部件"的耦合,只是多了B作为A和F变化的缓冲区。
public class A{
        public void aSay() {
            System.out.println("I am A");
        }
    }

    public class Base{

        public A a;
        public Base(A a){
            this.a=a;
        }
        public void baseSay(){
            a.aSay();
        }
    }

    public class B{
        public void put(Base base){
            base.baseSay();
        }
    }

    public static void main(String[] args){
        A a=new A();
        Base base=new Base(a);
        B b=new B();
        b.put(base);
    }

总结

解耦的本质就是将类之间的直接关系转换成间接关系,不管是类向上转型,接口回调还是适配器模式都是在类之间加了一层,将原来的直接关系变成间接关系,使得两类对中间层是强耦合,两类之间变成弱耦合关系。