在软件开发中,为了提高软件系统的可维护性和可复用性,增加软件的可扩展性和灵活性,程序员要尽量根据 7 条原则来开发程序,从而提高软件开发效率、节约软件开发成本和维护成本。

这 7 种设计原则是软件设计模式必须尽量遵循的原则,各种原则要求的侧重点不同。其中,开闭原则是总纲,它告诉我们要对扩展开放,对修改关闭;里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;单一职责原则告诉我们实现类要职责单一;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合度;合成复用原则告诉我们要优先使用组合或者聚合关系复用,少用继承关系复用。

1、开闭原则

原则定义:

软件实体应当对扩展开放,对修改关闭,这就是开闭原则的经典定义。这里的软件实体包括以下几个部分:
1.项目中划分出的模块
2.类与接口
3.方法开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。

实现原理:

可以通过“抽象约束、封装变化”来实现开闭原则,即通过接口或者抽象类为软件实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。

实例展示:

/*** 定义课程接口*/
public interface ICourse {String getName();  // 获取课程名称Double getPrice(); // 获取课程价格Integer getType(); // 获取课程类型
}/*** 英语课程接口实现*/
public class EnglishCourse implements ICourse {private String name;private Double price;private Integer type;//省略get,set,空参,满参
}// 测试
public class Main {public static void main(String[] args) {ICourse course = new EnglishCourse("小学英语", 199D, "Mr.Zhang");System.out.println("课程名字:"+course.getName() + " " +"课程价格:"+course.getPrice() + " " +"课程作者:"+course.getAuthor());}
}

项目上线,但是出现了节假日打折的情况出现,现在有以下这几种方法去修改:

1:修改接口(不可取,修改接口时其他的代码也得改!)

2:修改实现类(不可取,这样会有两个获取价格的方法!)

3:扩展实现方法(可取,不改变原有代码,功能可实现!)

直接添加一个子类 SaleEnglishCourse ,重写 getPrice()方法,这个方案对源代码没有影响,符合开闭原则,所以是可执行的方案

public class SaleEnglishCourse extends EnglishCourse {public SaleEnglishCourse(String name, Double price, String author) {super(name, price, author);}@Overridepublic Double getPrice() {return super.getPrice() * 0.85;}
}

开闭原则的作用

开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性的同时具备稳定性和延续性。具体来说,其作用如下。1. 对软件测试的影响
软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的测试代码仍然能够正常运行。
2. 可以提高代码的可复用性
粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性。
3. 可以提高软件的可维护性
遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护。

2、里氏替换原则

原则定义:

继承必须确保超类(被继承的类称为超类,继承的类称为子类)所拥有的性质在子类中仍然成立。里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。里氏替换原是继承复用的基础,它反映了基类与子类之间的关系,是对开闭原则的补充,是对实现抽象化的具体步骤的规范。

实现原理:

1、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
2、子类可以有自己的个性
3、覆盖或实现父类的方法时输入参数可以被放大
4、覆写或实现父类的方法时输出结果可以被缩小

实例展示:

1、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法,父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。
(略)2、子类可以有自己的个性
在继承父类属性和方法的同时,每个子类也都可以有自己的个性,在父类的基础上扩展自己的功能。前面其实已经提到,当功能扩展时,子类尽量不要重写父类的方法,而是另写一个方法,所以对上面的代码加以更改,使其符合里氏替换原则。
(略)3、覆盖或实现父类的方法时输入参数可以被放大
当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。(String 继承于CharSequence)
public class ParentClazz {public void say(String str) {System.out.println("parent execute say " + str);}
}public class ChildClazz extends ParentClazz {public void say(CharSequence str) {System.out.println("child execute say " + str);}
}
// 执行结果:
// parent execute say hello
// parent execute say hello
// 参数大小不一样,一直用的都是string,父类的4、覆写或实现父类的方法时输出结果可以被缩小
当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。
public abstract class Father {public abstract Map hello();
}public class Son extends Father {@Overridepublic Map hello() {HashMap map = new HashMap();System.out.println("son execute");return map;}
}

里式替换的作用:

里氏替换原则是实现开闭原则的重要方式之一。
它克服了继承中重写父类造成的可复用性变差的缺点。
它是动作正确性的保证。即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性。

3、依赖倒置原则

原则定义:

依赖倒置原则的原始定义为:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。其核心思想是:要面向接口编程,不要面向实现编程。依赖倒置原则是实现开闭原则的重要途径之一,它降低了客户与实现模块之间的耦合。由于在软件设计中,细节具有多变性,而抽象层则相对稳定,因此以抽象为基础搭建起来的架构要比以细节为基础搭建起来的架构要稳定得多。这里的抽象指的是接口或者抽象类,而细节是指具体的实现类。使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的任务交给它们的实现类去完成。

实现原理:

依赖倒置原则的目的是通过要面向接口的编程来降低类间的耦合性,所以我们在实际编程中只要遵循以下4点,就能在项目中满足这个规则。
每个类尽量提供接口或抽象类,或者两者都具备。
变量的声明类型尽量是接口或者是抽象类。
任何类都不应该从具体类派生。
使用继承时尽量遵循里氏替换原则。

实例展示:

public class T2 {public static void main(String[] args) {IDriver zhangsan = new Driver();Icar benz = new Benz();zhangsan.drive(benz);Icar bmw = new BMW();zhangsan.drive(bmw);}
}interface IDriver {//    司机职责就是驾驶汽车public void drive(Icar car);
}class Driver implements IDriver{//    司机职责就是驾驶汽车@Overridepublic void drive(Icar car) {car.run();}
}interface Icar {//    车的作用就是跑public void run();
}class Benz implements Icar {//    车的作用就是跑@Overridepublic void run() {System.out.println("奔驰车跑起来了");}
}class BMW implements Icar {//    车的作用就是跑@Overridepublic void run() {System.out.println("宝马车跑起来了");}
}

依赖倒置原则作用:

依赖倒置原则的主要作用如下。
依赖倒置原则可以降低类间的耦合性。
依赖倒置原则可以提高系统的稳定性。
依赖倒置原则可以减少并行开发引起的风险。
依赖倒置原则可以提高代码的可读性和可维护性。

软件设计的七大原则 --开闭原则 里氏替换原则 依赖倒置原则相关推荐

  1. 依赖倒置原则——举例说明Java设计模式中的依赖倒置原则

    依赖倒置原则--举例说明Java设计模式中的依赖倒置原则 一.前言 看官方定义 二.举例说明 2.1 例子介绍(无聊的可看看,着急的请跳过) 2.2 反例 2.1.1 反例1 (1)类图说明 (2)代 ...

  2. 里氏替换原则_代码需要有单一职责,还要开闭,里氏替换又是什么鬼?

    目录 单一职责原则: 开闭原则: 里氏替换原则: 单一职责原则: 每一个系统中的功能都表示一个职责,这些职责可以映射到模块(类)中, 且尽可能的保证这些类中没有功能上的重复,设计中每次应只关注一个职责 ...

  3. Java设计模式:1.1.认识六个原则(开闭,里氏替代,依赖颠倒)

    Hello,各位,好久没发布内容了,现在转做Java语言,目前基础已经学习一大半,正在钻研设计模式,第一天开始学习,废话不多说,走起!!! 我个人比较喜欢先概念再实战,这样可以提高自己在敲代码中的思维 ...

  4. 浅谈软件设计的七大原则

    软件设计原则这个话题看上去很大,乍一看确实不小,但是如果仔细去分析的话可以发现这些原则其实就是为了避免一些问题而提出的一些建议,这些建议呢普遍使用于软件的各个领域,所以给这些建议提高了一个档次就叫做原 ...

  5. 软件设计的七大设计原则

    一.前言 七大设计原则是23种设计模式的基础,体现了软件设计的思想,但并不是所有设计模式都遵循这七大设计原则,有些设计模式只遵循一部分设计原则,是对一些实际情况做的一些取舍.在我们项目中也并不一定完全 ...

  6. C#软件设计——小话设计模式原则之:依赖倒置原则DIP

    前言:很久之前就想动笔总结下关于软件设计的一些原则,或者说是设计模式的一些原则,奈何被各种bootstrap组件所吸引,一直抽不开身.群里面有朋友问博主是否改行做前端了,呵呵,其实博主是想做" ...

  7. 面向对象设计原则-03依赖倒置原则

    面向对象设计原则-03依赖倒置原则 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP)是 Object Mentor 公司总裁罗伯特·马丁(Rob ...

  8. 依赖倒置原则——面向对象设计原则

    前两节我们详细介绍了面向对象设计原则中的开闭原则和里氏替换原则,在本节中我们来介绍依赖倒置原则. 依赖倒置原则的定义 依赖倒置原则(Dependence Inversion Principle,DIP ...

  9. 设计模式之禅之六大设计原则-依赖倒置原则

    依赖倒置原则 依赖倒置原则的原始定义是: ● 高层模块不应该依赖低层模块,两者都应该依赖其抽象; ● 抽象不应该依赖细节; ● 细节应该依赖抽象. 那什么是抽象?什么又是细节呢? ---->在J ...

最新文章

  1. 锐界机器人_看着就很酸爽,2.7T V6双涡轮,车则试驾新福特锐界ST
  2. 1500+ FPS!目前最快的CNN人脸检测算法开源
  3. 1029 旧键盘 (20 分)(c语言)
  4. wap(dopra linux )命令,运营商定制的华为光猫Telnet命令恢复华为界面
  5. linux 进程的缓存区,Linux-标准I/O缓冲区位于进程中那个位置,堆区?栈区?还是其他位置?...
  6. math python 向上取整_Python成为专业人士笔记-各数学运算操作深度剖析
  7. BZOJ1055: [HAOI2008]玩具取名[区间DP]
  8. python元祖封包_[Day8]遷延蹉跎,來日無多-python終極指南:模組和封包,外掛般的超能力...
  9. 20200119:(leetcode)回文数(3种解法)
  10. http 网页突然报502 bad gateway,平台宕掉
  11. 又拍云推出区块链开发平台,覆盖多个公链
  12. Django使用pyjwt实现Token跨域认证登录过程实践
  13. SpringCloudAlibaba之Nacos
  14. 有一种空格叫做--不间断空格(空格保存到数据库变成了问号)
  15. N! hdu 1042
  16. SoC关键技术-HBM学习札记
  17. 微博--图片,视频,评论抓取
  18. linux系统部署微服务项目
  19. 字符串函数剖析(3)---strstr函数
  20. 深度可分离卷积(DepthwiseSeparableConvolution):Depthwise卷积与Pointwise卷积

热门文章

  1. matlab波形相似系数,如何用matlab计算波形相似系数
  2. 另一只眼看软件研发效能提升,软件研发效能的“人性”与“物性”
  3. 某微信小程序连锁超市响应参数解密
  4. 3D打印机T3升级corexy  制作过程(二)
  5. 华录智达科技有限公司入职六个月浅谈
  6. 小型数据库系统开发作业
  7. 自己动手写CSDN博客提取器源码分析之三:处理网页保存为pdf文件
  8. 计算机卡死快捷键,必看!电脑运行卡或软件卡死无响应,怎么办?
  9. 白狐微信公众号编辑器CMS系统源码
  10. 项目管理中的各种技术,分析图(简介+应用子过程)