zoukankan      html  css  js  c++  java
  • 设计模式|原则—依赖倒置原则

    依赖倒置原则

    定义:

    高层模块不应该依赖于底层模块,二者都应该依赖其抽象。

    抽象不应该依赖细节;细节应该依赖抽象。

    针对接口编程,不要针对实现编程。
    

    优点:

    可以减少类间的耦合性、提高系统稳定性,提高代码可读性和可维护性,可以降低修改程序所造成的风险。
    

    问题由来:

    类A直接依赖类B,假如要将类B改为依赖类C,则必须通过修改类A的代码来达成。这种场景下,类A一般是高层模块,负责复杂的业务逻辑,类B和类C是底层模块,负责基本的原子操作;假如要修改A,会给程序带来不必要的风险。

    解决方案:

    将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口I间接与类B和类C发生联系。

    代码示例:

    假设有这么一个场景,有一个名为Geely的人,有学习java、fe的方法:

    • Geely.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 15:48
     */
    public class Geely {
        public void studyJavaCourse() {
            System.out.println("Geely 在学习Java课程");
        }
    
        public void studyFeCourse() {
            System.out.println("Geely 在学习FE课程");
        }
    }
    
    • Test.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 15:52
     */
    public class Test {
        public static void main(String[] args) {
            Geely geely = new Geely();
            geely.studyJavaCourse();
            geely.studyFeCourse();
        }
    }
    

    那如果现在Geely想要学习Python课程,那就需要将Geely.java修改为:

    • Geely.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 15:48
     */
    public class Geely {
        public void studyJavaCourse() {
            System.out.println("Geely 在学习Java课程");
        }
    
        public void studyFeCourse() {
            System.out.println("Geely 在学习FE课程");
        }
    
        public void studyPythonCourse() {
            System.out.println("Geely 在学习Python课程");
        }
    }
    

    这种做法,就是面向实现编程,因为整个Geely就是一个实现类。这个实现类是要经常修改的,扩展性非常差。Test类是属于应用层的,高层的模块不应该依赖低层次的Geely,那我们试着解决这个问题。

    首先创建接口:

    • ICourse.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 16:06
     */
    public interface ICourse {
        void studyCourse();
    }
    

    具体实现什么课程,我们交给高层去实现。

    • JavaCourse.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 16:07
     */
    public class JavaCourse implements ICourse {
        public void studyCourse() {
            System.out.println("Geely 在学习Java课程");
        }
    }
    
    • FeCourse.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 16:08
     */
    public class FeCourse implements ICourse {
        public void studyCourse() {
            System.out.println("Geely 在学习FE课程");
        }
    }
    

    对Geely类进行修改:

    • Geely.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 15:48
     */
    public class Geely {
        public void studyImoocCourse(ICourse iCourse) {
            iCourse.studyCourse();
        }
    }
    

    测试类:

    • Test.java
    package com.design.principle.dependenceinversion;
    
    /**
     * @Author: JLU Tiger
     * @Date: 2019/8/29 15:52
     */
    public class Test {
        public static void main(String[] args) {
            Geely geely = new Geely();
            geely.studyImoocCourse(new JavaCourse());
            geely.studyImoocCourse(new FeCourse());
        }
    }
    

    这样就尽量的减少了耦合,如果需要扩展,直接创建类实现ICourse即可。

  • 相关阅读:
    【转】C#进阶系列——WebApi 接口参数不再困惑:传参详解
    微信内测小程序,苹果你怎么看?
    给你一个团队,你应该怎么管?
    ios修改产品名
    【原创】windows下搭建vue开发环境+IIS部署
    【原】“系统”重新启动
    Ubuntu root密码修改
    【转】网络编程常见问题总结
    Python + Selenium -Python 3.6 3.7 安装 PyKeyboard PyMouse
    python3 获取当前路径及os.path.dirname sys.path.dirname的使用
  • 原文地址:https://www.cnblogs.com/jlutiger/p/11430419.html
Copyright © 2011-2022 走看看