Java七大设计原则(6/7)——合成复用原则

158 阅读2分钟

本文已参加「新人创作礼」活动,一起开启掘金创作之路。

定义

合成复用原则:尽量使用对象组合,而不是继承来达到复用的目的。

合成复用原则同里氏替换原则相辅相成的,两者都是开闭原则的具体实现规范。

组合复用可以使系统更加灵活,降低类与类之间的耦合度。

而使用继承,会大大增加类与类之间的耦合度,因为假如哪天被继承类的业务需要修改,或者被继承类的业务需要

另一个类来代替,那么继承类所继承的父类业务也需要去修改,这样做增大了工程量。并且继承子类还会继承父类

一些可能不想暴露的细节,这样并不安全。


代码实现

不使用合成复用原则

假设现在要出门,我们选择一双鞋穿出去。

定义一个Nike类。

/**
 * @author John117
 * @date 2022/05/24  12:24
 */
public class Nike {
    //穿鞋方法
    public void putOn() {
        System.out.println("穿的是Nike鞋");
    }
}

定义一个Foot类(其实这里用接口更符合规范,但是为了方便直接定义为类)。

/**
 * @author John117
 * @date 2022/05/24  12:29
 */
public class Foot extends Nike {
    // 出门方法
    public void goOut() {
        putOn();
    }
}

测试

/**
 * @author John117
 * @date 2022/05/24  12:29
 */
public class Test {
    public static void main(String[] args) {
        new Foot().putOn();
    }
}

这么看其实没什么问题,但是假如现在要换一双鞋出门,那就必须改Foot类的继承,耦合太高了。

使用合成复用原则

定义Nike类和Adidas类

/**
 * @author John117
 * @date 2022/05/24  12:32
 */
public class Nike {
    public void putOn() {
        System.out.println("穿的是Nike鞋");
    }
}
/**
 * @author John117
 * @date 2022/05/24  12:33
 */
public class Adidas {
    public void putOn() {
        System.out.println("穿的是Adidas鞋");
    }
}

这时候就需要更改Foot类,不使用继承

方法一

可以这样写

/**
 * @author John117
 * @date 2022/05/24  12:33
 */
public class Foot {
    Adidas adidas = new Adidas();
    Nike nike = new Nike();

    public void goOutByAdidas() {
        adidas.putOn();
    }

    public void goOutByNike() {
        nike.putOn();
    }
}

然后测试

/**
 * @author John117
 * @date 2022/05/24  12:37
 */
public class Test {
    public static void main(String[] args) {
        new Foot().goOutByAdidas();
        new Foot().goOutByNike();
    }
}

方法二

也可以这样写

/**
 * @author John117
 * @date 2022/05/24  12:33
 */
public class Foot {

    public void goOutByAdidas(Adidas adidas) {
        adidas.putOn();
    }

    public void goOutByNike(Nike nike) {
        nike.putOn();
    }
}

测试

/**
 * @author John117
 * @date 2022/05/24  12:37
 */
public class Test {
    public static void main(String[] args) {
        new Foot().goOutByAdidas(new Adidas());
        new Foot().goOutByNike(new Nike());
    }
}

总结

合成复用原则其实就是,尽量使用聚合和组合的方式,进行解耦,降低耦合性,而不是使用继承