设计模式(五)设计原则part2

SOLID五种原则中前面我们学习了SOLI,那么就还剩下一种,D,也就是DIP,我们叫做依赖反转原则 Dependency Inverion Principle。看到这个名字是否很熟悉,因为我们的框架中经常提到的是,控制反转,依赖注入,而依赖反转是设计原则中的一种。

所以我们结合控制反转和依赖注入来学习依赖反转。

控制反转IOC

提到控制反转和依赖注入对于Java工程师而言,很容易联想到Spring框架,但这两个概念并不是Spring特有的。

package DesignPrinciple.DIP;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description: IOC测试类
 */ 
public class UserServiceTest {
    public static boolean doTest(){
        // ...业务测试逻辑
        return true;
    }

    public static void main(String[] args) {
        if (doTest()){
            System.out.println("Test Succeed");
        }else{
            System.out.println("Test Failed");
        }
    }
}

首先我们看上面这个类,对于上面的测试类中,所有的流程都由程序员在doTest函数中进行控制。

当我们自己设计一个测试框架之后,代码如下:

  • 先对每个测试用例进行类的实现
package DesignPrinciple.DIP;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description:
 */
public abstract class IOCTestCase {
    public void run(){
        if (doTest()){
            System.out.println("Test Succeed");
        }else{
            System.out.println("Test Failed");
        }
    }
    public abstract boolean doTest();
}

  • IOC测试类
package DesignPrinciple.DIP;

import java.util.ArrayList;
import java.util.List;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description: 控制反转的例子
 */


public class IOC {
    private static final List<IOCTestCase> testCases = new ArrayList<>();

    public static void register(IOCTestCase testCase){
        testCases.add(testCase);
    }

    public void runTestCases(){
        for (IOCTestCase testCase: testCases){
            testCase.run();
        }
    }
}

那么对于这个框架,我们可以对之前的UserServiceTest进行修改

package DesignPrinciple.DIP;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description: IOC测试类
 */
public class UserServiceTest extends IOCTestCase{


    @Override
    public boolean doTest() {
        return false;
    }
}

这就是一个控制反转的例子,这里的控制其实是对程序执行流程的控制,在使用框架前,整个程序执行的流程其实都是程序员来决定并且进行代码的编写。而使用框架之后,整个程序的执行流程其实都在框架里面,程序员要对样例进行编写,只需要对照框架给出的拓展点,也就是IOCTestCase,进行需求代码的编写就行了。

所以控制反转其实是一种比较笼统的设计思想。

依赖注入 DI

依赖注入Dependency Injection其实就是不通过new()的方法在类的内部创建当前类依赖的类对象。而是将依赖的类对象在外部创建后,通过构造函数,注解,函数参数等方式传递给类使用。

这个其实就比较简单了,我们平时用的都比较多,而在Spring中就可以通过Autowired注解等方式对依赖进行注入,这个时候是不需要通过new()方法进行依赖的类对象进行创建的。

依赖反转 DIP

知道了控制反转和依赖注入,其实依赖反转就是两种的结合,一个是依赖,就是类与类之间的依赖关系,一个是反转,就是将依赖关系反转过来。这种设计原则可以让代码变的拓展性更强,具体是怎么实现的呢,下面通过一个例子进行学习。

比如一个手机工厂,前几年是生产的是华为手机,


package DesignPrinciple.DIP;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description:
 */
public class Huawei {
    public void getParameter(){
        // ... 业务需求
    }
}

package DesignPrinciple.DIP;

/**
 * @time: 2022/10/20
 * @author: yuanyongan
 * @description:
 */
public class PhoneFactory {
    private Huawei huawei;

    public PhoneFactory(Huawei huawei){
        this.huawei = huawei;
    }

    public void produce(){
        huawei.getParameter();
        //...生产手机
    }
}

目前来看,这个依赖关系没什么问题,手机工厂依赖Huawei,但是如果有一天,这个工厂不生产Huawei手机了,而是生产Xiaomi呢,那依赖的Huawei是不是又得修改了,而这个修改工作是非常大的。依赖关系如下
在这里插入图片描述

那么依赖反转其实就是为了解决这个问题,基于依赖反转原则,我们可以创建一个新的类Phone,修改代码如下。


public abstract class Phone {
    abstract void getParameter();
}

public class Huawei extends Phone{
    public void getParameter(){
        // ... 业务需求
    }
}

public class PhoneFactory {
    private Phone phone;

    public PhoneFactory(Phone huawei){
        this.phone = huawei;
    }

    public void produce(){
        phone.getParameter();
        //...生产手机
    }
}



这个时候的依赖关系其实是这样的,这样的依赖关系其实就可以让我们的代码可拓展性更强。而这也是依赖反转原则的目的所在。将依赖的关系反转过来,让代码的可拓展性变强。
在这里插入图片描述

代码地址:https://gitlab.com/WyLmYYA
欢迎交流

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值