面向对象设计原则——java设计模式(一)

设计原则的目的

  1. 确保可维护性。软件能够被理解、修改、扩展。
  2. 确保可复用性。实现设计方案或者源代码的复用。

单一职责原则

一个对象应该只包含单一职责,并且该职责被完整的封装在一个类中。

  • 单一职责原则(Single Responsibility Principle, SRP),是最简单也是最难运用的设计原则,用于控制类的粒度。是高内聚、低耦合的知道方针。
  • 一个类的职责越多,被复用的可能性越小。当其中一个职责变化时,可能会影响到其他职责的运作。因此需要职责分离。

实例

  • 客户信息图形统计模块,将客户信息通过图形展示。
    • 初始版本:获得数据库连接、查询用户信息、创建和显示图表均放在一个类中,无论是修改图表显示还是数据库连接方式,都需要修改这个类。违反单一职责原则。
    • 重构版本:拆分为3个类。
      • DBUtil负责连接数据库。
      • CustomerDao负责操作数据库的表,获取用户信息。
      • CustomerDataChart负责图表相关,包括显示和生成。
  • 180504.single.png

开闭原则

软件实体应该对扩展开放,对修改关闭。

  • 开闭原则(Open-Closed Principle, OCP),是最重要的设计原则,要求尽量在不修改原有代码的情况下进行扩展,关键是抽象化

里氏替换原则

所有引用基类的地方必须能透明地使用其子类。

  • 里氏代换原则(Liskov Substitution Principle, LSP),是实现开闭原则的重要方式之一,要求将基类对象替换为子类对象时,程序没有错误或异常。
  • 基类可以设计为抽象类、接口,增加新的功能通过增加新的子类实现,无需修改原有代码。

依赖倒转原则

高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不应该依赖于细节,细节应该依赖于抽象。

  • 依赖倒转原则(Dependency Inversion Principle, DIP),是面向对象设计的主要实现机制之一,要求针对接口编程。只需要扩展抽象层,通过配置文件指定实现类。

关系

  • 开闭原则是目标里氏替换原则是基础依赖倒转原则是手段,相互补充,角度不同。

实例

  • 将存储在txt或者excel等文件中的客户数据存储到数据库中。
    • 初始版本:通过局部变量调用数据转换类,因为数据来源不一致,需要经常修改CustoerDao代码,更换数据转换类,违反开闭原则。
      180504.opne.png
    • 重构版本:针对数据转化抽象类编程,通过配置文件指定实现类。
      180504.opne2.png

接口隔离原则

客户端不应该依赖那些它不需要的接口。

  • 接口隔离原则(Interface Segregation Principle, ISP),要求每一个接口承担一种相对独立的角色,使接口的职责相对单一。
  • 需要注意接口也不能划分太小,否则会接口泛滥,通常接口中仅包含某一类用户定制的方法。

实例

  • 客户数据显示模块。
    • 初始版本:接口中包含读取文件、转化为xml格式、创建和展示图表、创建和展示文字报表,职责多样,很多类只需要实现其中的部分功能,但是仍然需要实现不相关的接口。不符合接口隔离原则。
      180504.interface.png
    • 重构版本:根据数据源格式和生成报告还是图表确定4个接口,每个接口角色较为单一。
      180504.interface2.png

合成复用原则

优先使用对象组合,而不是继承来达到复用的目的。

  • 合成复用原则(Composite Reuse Principle, CRP),要求优先使用关联(包括组合聚合)来复用,这样可以降低类之间的耦合度,使系统更加灵活。
  • 通过继承的复用会将基类的实现暴露给子类,破坏封装性,称为白箱复用;通过关联复用则成员变量的内部实现不可见,称为黑箱复用

实例

  • 访问数据库的客户信息。
    • 初始版本:dao类需要使用数据库工具类,通过继承来复用。如果更换数据库,无论是修改dao类为继承另一个工具类,还是直接修改工具类,都将违反开闭原则。
      180504.comb.png
    • 重构版本:将工具类的父类作为dao类的成员变量使用,dao类针对父类编程。不同数据库的工具类可以继承父类工具类,从而实现功能的扩展。
      180504.comb2.png

迪米特法则

每一个软件单位对其他单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

  • 迪米特法则(Law of Demeter, LoD),要求尽可能少与其他实体发生相互作用,这样可以降低系统之间的耦合度。
  • 一个对象应该只和自己的朋友相互作用,包括:
    1. 对象本身。
    2. 依赖对象:以参数形式传入方法的对象、创建的对象。
    3. 关联对象:成员变量,包含成员变量这一集合的元素。

实例

  • 操作窗口按钮和响应。
    • 初始版本:一个按钮被单击时,列表框、组合框、文本框、文本标签都会改变。这些控件关系复杂,在窗口中新增控件时,需要修改和它交互的所有控件的源代码,扩展性很差。
      180504.dimi.png
    • 重构版本:使用控件交互的中间类,降低控件的耦合度,新增控件只需要修改中间类即可。
      180504.dimi2.png

猜你喜欢

转载自blog.csdn.net/qq_40369829/article/details/80194225