博客
关于我
1-六大设计原则
阅读量:404 次
发布时间:2019-03-05

本文共 3657 字,大约阅读时间需要 12 分钟。

设计模式之禅

1. 单一职责原则

定义

单一职责原则(Single Responsibility Principle,SRP)是软件开发中的一个核心原则。它的英文名称是 single responsibility principle,简称SRP。简单来说,有且仅有一个原因引起类的变更。一个类不能承担多于一个职责。

优点

  • 降低复杂性:类的设计更加清晰,结构更有层次感。
  • 提高可读性:代码更易于理解,因为每个类都专注于一件事。
  • 降低变更风险:当需要修改一个类时,只需要关注它的职责,不会影响到其他功能。
  • 促进可维护性和扩展性:代码更容易维护和扩展,因为每个类的功能单一。

实践建议

  • 接口和方法设计:确保接口和方法都符合单一职责原则。
  • 类设计:尽量让类的设计接近单一职责原则。

2. 里氏替换原则

定义

里氏替换原则(Liskov Substitution Principle,LSP)是软件开发中的一个重要原则。它的英文名称是 Liskov Substitution Principle,简称LSP。它的核心思想是:所有引用基类的地方必须透明地使用子类的对象。使用者察觉不到是基类还是子类。例如,白马和黑马都是马的子类。如果一个操作 rideHorse 以马为参数,那么白马和黑马也可以作为参数。然而,反过来则不成立:白马和黑马能出现的地方,马则不能。

里氏替换原则的四点含义

  • 子类必须完全实现父类的方法:如果一个子类完全实现了父类的方法,那么它可以被用来替换父类。
  • 子类可以有自己的个性:子类可以在父类的基础上增加自己的功能。
  • 覆盖或实现父类方法时输入参数可以放大:子类方法的输入参数范围可以比父类更大。
  • 覆盖或实现父类方法时输出结构可以缩小:子类方法的输出结构可以比父类更小。
  • 实践建议

    • 尽量避免子类的个性:用里氏替换原则时,尽量让子类看起来像是父类的扩展,而不是完全不同的东西。
    • 把子类当做父类使用:在设计类的时候,尽量让子类可以替换父类的使用。

    3. 依赖倒置原则

    定义

    依赖倒置原则(Dependence Inversion Principle,DIP)是软件开发中的一个重要原则。它的英文名称是 Dependence Inversion Principle,简称DIP。在Java中的表现是:

    • 模块之间的依赖通过抽象(如接口或抽象类)进行,而不是通过具体的实现类进行。
    • 接口或抽象类不依赖于实现类。
    • 实现类依赖于接口或抽象类。

    依赖倒置原则的简单解释

    • 正常思维:如果我要开车,我需要一个具体的车(如奔驰车或宝马车)。
    • 倒置思维:我不需要直接依赖具体的车,而是依赖车的接口或抽象类。这意味着车的具体实现不影响我对车的操作。

    实践建议

    • 面向接口编程:每个类尽量有接口或抽象类。
    • 变量表面类型尽量是接口或抽象类
    • 避免从具体类派生:尽量避免直接从具体类继承。
    • 尽量避免覆盖基类的方法
    • 结合里氏替换原则使用

    4. 接口隔离原则

    定义

    接口隔离原则(Interface Segregation Principle,ISP)是软件开发中的一个重要原则。它的英文名称是 Interface Segregation Principle,简称ISP。它有两种定义:

  • 客户端不应该依赖它不需要的接口。
  • 类之间的依赖关系应该建立在最小的接口上。
  • 接口隔离原则的例子

    假设我们有一个关于“美女”的接口:

    public interface Beautiful {    void hasBeautifulFace();    void hasGoodFigure();    void hasGoodPersonality();}

    随着时代的发展,审美标准的变化让“有气质好的美女”可以不再满足“有脸蛋好”和“有身材好”的标准。因此,我们可以将“脸蛋好”和“身材好”封装成一个接口,而“气质好”单独作为一个接口:

    public interface BeautifulFace {    void hasBeautifulFace();}public interface BeautifulFigure {    void hasGoodFigure();}public interface BeautifulPersonality {    void hasGoodPersonality();}

    这样,客户端只需要依赖它需要的接口,而不依赖它不需要的接口。

    实践建议

    • 接口只服务一个子模块或业务逻辑:确保接口的粒度合适。
    • 压缩接口中的public方法:通过业务逻辑减少接口中的public方法。
    • 已被污染的接口:如果接口已经被污染(如需要添加新的方法),建议使用适配器模式。
    • 了解环境,拒绝盲从:不要一味地遵循接口隔离原则,而是根据实际情况来决定。

    5. 迪米特原则

    定义

    迪米特原则(Demeter's Law,Law of Demeter,LoD),也被称为最少知识原则(Least Knowledge Principle,LKP)。它的英文名称是 Law of Demeter,简称LoD。其核心思想是:一个对象应该对其他对象有最少的了解。具体来说,一个对象只能调用其他对象的public方法,其他的它不需要知道。

    迪米特原则的含义

  • 只和直接朋友交流:直接朋友是指出现在成员变量和方法参数中的类。在方法体中出现的类则不是朋友。
  • 朋友也是有距离的:即使朋友也是朋友,也不一定可以随意访问其成员变量或方法。
  • 是自己的就是自己的:如果一个方法放在自己的类中可以,那么就放在自己的类中。
  • 谨慎使用Serializable:序列化对象可能会暴露内部状态,需要谨慎使用。
  • 迪米特原则的例子

    安装软件的过程:

    public class InstallSoftware {    public void install() {        wizard.installSoftware();    }}public class Wizard {    public Software installSoftware() {        // install logic    }}public class Software {    public void installWizard() {        // install logic    }}

    如果 wizard 的方法返回参数变更,会导致 installSoftware 也需要跟随修改,这种耦合度过高。改进方式是将 wizard 的方法改为私有,封装成一个 installWizard() 方法,提供给 installSoftware

    实践建议

    • 类间解耦:迪米特原则的核心是类间解耦。如果有耦合,需要谨慎使用。
    • 结合其他原则使用:如依赖倒置原则和里氏替换原则。

    6. 开闭原则

    定义

    开闭原则(Open-Closed Principle,OCP)是软件开发中的一个重要原则。它的英文名称是 Open-Closed Principle,简称OCP。它的核心思想是:一个软件实体(如类、模块或函数)对扩展开放,对修改关闭。通过扩展实现变化,而不是通过修改。

    开闭原则的具体含义

    • 对扩展开放:当需要添加新的功能时,可以通过扩展现有的类或模块来实现,而不需要修改现有的代码。
    • 对修改关闭:当需要修改现有功能时,可以通过扩展或替换现有的代码来实现,而不需要修改现有的代码结构。

    开闭原则的例子

    假设我们有一个交通工具类:

    public abstract class Vehicle {    abstract void drive();}public class Car extends Vehicle {    @Override    void drive() {        // drive logic    }}public class Bike extends Vehicle {    @Override    void drive() {        // bike drive logic    }}

    如果需要新增一种交通工具,比如摩托车(Motorcycle),我们只需要创建一个新的子类:

    public class Motorcycle extends Vehicle {    @Override    void drive() {        // motorcycle drive logic    }}

    而不需要修改现有的 Vehicle 类或 Car 类。

    实践建议

    • 开放接口或抽象类:通过接口或抽象类实现开闭原则。
    • 使用策略模式:在需要频繁修改功能时,可以通过策略模式来实现开闭原则。
    • 合理设计扩展点:在设计的时候,合理预见可能的扩展点,方便以后维护和扩展。

    通过遵循这些设计模式,我们可以设计出更高质量、更易于维护和扩展的软件系统。

    转载地址:http://vphwz.baihongyu.com/

    你可能感兴趣的文章
    MYSQL 幻读(Phantom Problem)不可重复读
    查看>>
    mysql 往字段后面加字符串
    查看>>
    mysql 快速自增假数据, 新增假数据,mysql自增假数据
    查看>>
    Mysql 报错 Field 'id' doesn't have a default value
    查看>>
    MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
    查看>>
    Mysql 拼接多个字段作为查询条件查询方法
    查看>>
    mysql 排序id_mysql如何按特定id排序
    查看>>
    Mysql 提示:Communication link failure
    查看>>
    mysql 插入是否成功_PDO mysql:如何知道插入是否成功
    查看>>
    Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
    查看>>
    mysql 数据库备份及ibdata1的瘦身
    查看>>
    MySQL 数据库备份种类以及常用备份工具汇总
    查看>>
    mysql 数据库存储引擎怎么选择?快来看看性能测试吧
    查看>>
    MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
    查看>>
    MySQL 数据库的高可用性分析
    查看>>
    MySQL 数据库设计总结
    查看>>
    Mysql 数据库重置ID排序
    查看>>
    Mysql 数据类型一日期
    查看>>
    MySQL 数据类型和属性
    查看>>
    mysql 敲错命令 想取消怎么办?
    查看>>