一、单一职责原则(SRP)
二、开闭原则(OCP)对扩展开放,对修改关闭三、里氏替换原则(LSP)父类的属性和方法必须完全可以被继承,不会出现父类方法被子类使用出现不符合的情况四、依赖倒置原则(DIP)通过 抽象接口 来定义模块之间的依赖关系五、接口隔离原则(ISP) 拆接口,避免继承类 重复实现 接口内容。
三大基本面向对象设计原则
-针对接口编程,而不是针对实现编程
-优先使用对象组合,而不是类继承
-封装变化点
一.单一职责原则(SRP)
1、定义
一个类只负责一个功能领域中的相应职责,或者可以定义为:就一个类而言,应该只有一个引起它变化的原因。理解:单一职责原则是实现高内聚、低耦合的指导方针,它是最简单但又最难运用的原则每个类只负责单一的功能,该类尽量将一个功能做到极致。
避免在一个多次修改一个类,多次用if,转继承。
二、开闭原则(OCP)
1、定义
一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。软件实体:软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类理解:抽象化是开闭原则的关键开闭原则就是一个目标,其它五大原则都是实现手段,它就像一个口号,你们都要奔着这个口号来多次用if,转继承。
三、里氏替换原则
1、定义:
子类可以扩展父类的功能,但不能改变父类原有的功能派生类(子类)对象可以在程序中代替其基类(超类)对象。程序中的对象不管出现在什么地方,都应该可以使用其派生类(子类)的对象进行替换,而不影响程序运行的正确性。子类一般不要覆写父类的方法,尽量直接使用父类的方法即可。(避免父类的方法返回true,而子类覆写的方法返回false)理解:
- 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。
- 子类中可以增加自己特有的方法。
- 当子类的方法重载父类的方法时,方法的前置条件(方法的输入,入参)要比父类的入参更宽松。
- 当子类的方法实现父类的方法时(重写,重载,实现抽象方法),方法的后置条件(输出、返回值)要比父类更严格或相等。
2、为啥有?
里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,它反映了基类与子类之间的关系,是对开闭原则的补充。3、优点(继承的优点??)
- 约束继承泛滥,它也是开闭原则的一种很好的体现。
- 提高了代码的重用性。
- 降低了系统的出错率。类的扩展不会给原类造成影响,降低了代码出错的范围和系统出错的概率。
- 加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性、可扩展性,降低需求变更时引入的风险。
四、依赖倒置原则(DIP)
1、定义
a.高层模块不应该依赖低层模块,二者都应该依赖其抽象;b.抽象不应该依赖细节;细节应该依赖抽象。2、为什么需要遵守依赖倒置原则
高层:客户端、服务消费者、方法调用者……(可能变动、依赖性高)
低层:服务端、服务提供者、方法实现者,细节实现者……(易变动、通常需要扩展)
抽象:交互行为、策略、契约、流程、业务模型……(稳定、可重用)
传统系统:高层模块依赖低层模块。
DIP第一层境界:低层模块依赖高层模块。
DIP第二层境界:无论高层模块或低层模块实现的细节,都依赖于独立出来的抽象层。
3、在面向对象设计中如何实现依赖倒置原则
1、基础:依赖于抽象即:程序中所有的依赖关系都应该终止于抽象类或者接口中;而不应该依赖于具体类。
编程时可以这样做:(1)、类中的所有成员变量必须是接口或抽象,不应该持有一个指向具体类的引用或指针。 即所有具体类只能通过接口或抽象类连接。 不应该:HashMap map; 应该:Map map;(2)、任何类都不应该从具体类派生。(3)、任何方法都不应该覆写它的任何基类中已经实现的方法。(里氏替换原则)(4)、任何变量实例化都需要实现创建模式(如:工厂方法/模式),或使用依赖注入框架(如:Spring IOC)。注:
有些书籍和文章把DIP等同于面向接口编程;
个人理解是面向接口编程只是DIP的基础,而核心是"依赖倒置"。
4、依赖倒置原则的实例应用
4-1、案例
4-2、在系统架构中的应用:
1、数据存储 传统: 业务层在不同数据类型的CURD地方,直接调用不同数据系统(Mysql/Mongo/Rides缓存/本地文件系统)的相关接口,把数据保存到相应系统。 DIP: 抽象数据存储层(DAO),DAO模块实现不同数据系统的接口; 业务层调用DAO层接口传入不同类型数据,DAO层适配到相应数据系统。 2、消息传输 通常: 上层通过调用下层接口,发消息给下层。 一般情况上层需要同步等待下层处理后的响应。 DIP: 通过消息队列(Message Queue)解耦,实现异步传输; 上层调用MQ的发送消息接口,消息发送到MQ,下层调用MQ获取消息的接口进行消费; 这时上/下层都可以轻松进行扩展。 注意:如果上层实时关注下层的处理结果,MQ就不适用。五、接口隔离原则(ISP)
1、定义
a.客户端只依赖于它所需要的接口;它需要什么接口就提供什么接口,把不需要的接口剔除掉。b.类间的依赖关系应建立在最小的接口上。
隔离三个接口,避免子类重复实现
2、实例应用
internal interface IQueryScore
{
// 查询成绩
public void queryScore();
// 打印成绩单
public void printScore();
}
internal interface IOperateScore
{
// 修改成绩
public void updateScore();
// 添加成绩
public void saveScore();
// 删除成绩
public void delete();
// 计算总分
public double sum();
// 计算平均分
public double avg();
}
internal class StudentOperate : IQueryScore
{
public void printScore()
{
// 查询成绩
throw new NotImplementedException();
}
public void queryScore()
{
//打印成绩单
throw new NotImplementedException();
}
}
internal class TeacherOperate : IQueryScore, IOperateScore
{
public double avg()
{
throw new NotImplementedException();
}
//....
}
3、自己理解:
拆接口,避免接口继承类重复实现。(26条消息) C#设计模式六大原则 - 开闭原则_c# 开闭原则_familychase的博客-CSDN博客
https://blog.csdn.net/qq_34482621/article/details/103616713
标签:原则,子类,接口,设计,父类,方法,public From: https://www.cnblogs.com/buzheng11/p/17665246.html