zoukankan      html  css  js  c++  java
  • 依赖反转原则

    首先,什么是依赖反转,为什么叫反转?

    高层不应该依赖细节,细节应该依赖高层。


    什么是高层?什么是细节?对一个系统来说,业务逻辑是高层,其他是细节。业务逻辑是仅仅包括用例、业务实体部分,不包括任何框架、存储(数据库)、其他系统等部分,是纯粹的。其他细节,包括框架、数据库、消息队列,都是细节。业务逻辑应该不依赖任何细节。细节的实现可以任意替换而不影响业务逻辑。这样的业务逻辑,可以测试、容易测试。

    拿通常的Java Web应用来说,一般我们使用的包括:Controller->Service->DAO->数据库。 其中,Service是高层,包含业务逻辑,其他都是细节。

    为什么叫“反转”,从调用顺序来讲,Service是依赖DAO来实现业务数据的存取的,那么这时候高层就依赖了细节。但如果我们在Service层抽象一个DAO接口,让实际的DAO从这个接口派生一个类出来。那么Service这个模块就不依赖于DAO的实现,而是依赖了一个内部的接口。这样调用的方向和依赖的方向就相反了,称之为“反转”。例子:【Service->IDAO】<-DAOImpl->数据库。

    依赖注入和依赖反转的关系

    依靠框架的依赖注入功能,我们很容易实现依赖反转的时候实现实例的注入。

    业务对象:

    public class QuizServiceImpl implements QuizService {
        private BankDAO bankDAO;
        private QuizDAO quizDAO;
    

     在业务对象里面,我们定义了两个DAO,都是接口。

    在外部实现的时候,我们首先派生两个对象,实现这两个DAO接口。然后用Spring的Configuration功能,将这些接口的实现注入到Service中。Service完全不知道Spring框架、数据库的存在,他只关注自己的业务逻辑,以及自己声明的两个DAO接口。

    @Configuration
    public class ServiceConfig {
        @Bean
        BankDAO bankDAO(){
            return new MemoryBankDAOImpl();
        }
        @Bean
        QuizDAO quizDAO(){
            return new MemoryQuizDAOImpl();
        }
        @Bean
        QuizService quizService(BankDAO bankDAO,QuizDAO quizDAO){
            QuizServiceImpl quizService=new QuizServiceImpl();
            quizService.setBankDAO(bankDAO);
            quizService.setQuizDAO(quizDAO);
            return quizService;
        }
        @Bean
        QuestionAdminService questionAdminService(BankDAO bankDAO){
            QuestionAdminServiceImpl questionAdminService=new QuestionAdminServiceImpl();
            questionAdminService.setBankDAO(bankDAO);
            return questionAdminService;
        }
    }
    

      这样我们就可以在Controller等地方,使用@Autowired对QuiService进行自动注入。而Service完全不知道这些细节的存在!当然也就不存在依赖。

    通过依赖反转,高层的业务逻辑和各种细节完全解耦。你甚至可以这么做:一个工程写业务逻辑,然后打包成一个jar,另外一个实现的工程引用这个jar,把数据库、Controller等实现了,完成完整功能。

  • 相关阅读:
    xcode5 ios6程序图标去掉阴影
    ios程序启动时去掉状态栏
    ios启动图标程序适配
    c语言基础:各种数据类型的输出占位符
    c语言变量作用域问题
    JS 学习笔记--11---内置对象(Global/Math)
    JS 学习笔记--10---基本包装类型
    JS 学习笔记--9---变量-作用域-内存相关
    JS 学习笔记--8---Function类型
    JS 学习笔记--6---日期和时间
  • 原文地址:https://www.cnblogs.com/bobdeng/p/8477072.html
Copyright © 2011-2022 走看看