加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

增删改查也有设计模式——依赖倒置原则另解

发布时间:2020-12-14 05:05:12 所属栏目:百科 来源:网络整理
导读:一个增删改查的例子解读面向接口编程和依赖倒置原则 依赖倒置原则介绍 依赖倒置原则包括两个部分 .高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。 例子 现在有如下场景和需求: 老板要
一个增删改查的例子解读面向接口编程和依赖倒置原则

依赖倒置原则介绍

依赖倒置原则包括两个部分

  • .高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
  • 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。

    例子

    现在有如下场景和需求:
    老板要求设计任务模块,包括发布任务和撤回任务等。


    假设这个需求只给了几个小时去做,那肯定是来不及设计了,写到哪算哪。
    定义撤回接口的控制层如下

@RequestMapping(‘cancel‘)
@ResponseBody
public String cancelTask(Task task){
  // TODO 调用service的撤回接口
  return "{‘status‘:‘success‘}";
}

重点来了

这个时候已经写到这个地方了,服务层的cancel接口还没写好,因为在SpringMVC数据自动绑定的时候有了一个task对象,自然而然会联想到定义如下接口

public void cancel(Task task) throws ServiceException{};
而不是
public void cancel(String taskId) throws ServiceException{}

因为我手头有一个现成的task对象,我首先想到的传递参数就是task。两种差异也很简单,第二个需要在代码里多一个

Task task = this.findOneById(taskId); //因为是在service层的代码,一般都有findOneById这个接口

好了,因为我已经有task,所以这个时候我会很自然的给我两种暗示:

  • 如果我接受的参数是taskId我需要在和数据库做IO,如果调用方已经IO过一次了那我这个动作不是多余的吗
  • 调用方应该可以保证传给我的task是正确的数据

这里已经出现了错误的依赖的问题了
1 在定义接口时我们假设传进来的参数是数据库中最新的,但是这个根本无法保证。撤销接口的职责是什么?是将任务的状态从处理中变为待处理
2 高层和底层都依赖了实现,因为这里是基于我已经有了task对象,不想再IO消耗性能这段已经存在的代码逻辑去定义接口的
正确的应该是
当定义撤回接口时应该抛开已有的代码,去想这个接口的职责:变更状态,做其他操作
1 变更状态只需要id即可,其他操作也不依赖于高层的传递参数
2 定义接口时应该考虑他的职责去定义抽象,而代码实现应该遵守这个抽象所要实现的功能

这个就是

  • .高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。
  • 抽象不应该依赖于具体实现,具体实现应该依赖于抽象。
    同样也是

    面向接口编程

上面是自己开发过程中发现的另解,通解如下

依赖倒置原则实际讲的是高层调用低层时不应该通过实现类去调用,而是通过接口去调用,这样一旦低层出现了较大的变动,上层不会有太大波动。

假设如下场景

学生读书

public class Student{
  public void read(Honglou honglou){
    // 遍历每一行
    for(Line line: honglou.getLines){
    // 小明一行一行看
      this.see(line);
    }
  }
}
public class Honglou{
  public List<Line> getLines(){};
}

此时小明依赖于具体类Honglou,一旦小明想读其他书(使用其他实现)就无法实现了。

如果此时定义一个IBook类作为基类:

public class Student{
  public void read(IBook book){
    // 遍历每一行
    for(Line line: book.getLines){
    // 小明一行一行看
      this.see(line);
    }
  }
}
public interface IBook{
  public List<Line> getLines();
}

这样一旦小明要看其他的书,在参数传递时修改具体派生对象就可以了。这个原则属于设计模式中比较常用的原则,很多设计模式都是定义一些派生类去实现接口。如抽象工厂类,定义一组接口,由具体工厂类去实现,当需要切换其他模式的时候,切换实现类即可。策略模式:定义一个算法接口,要求他们可以随时切换,不同的算法派生类都实现同一个接口。算法调用类依赖于接口而不是具体策略类。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读