面向对象六大基本原则
来源:互联网 发布:淘宝联盟保持高佣金 编辑:程序博客网 时间:2024/05/22 17:06
在学习或者项目开发中,经常会碰到设计原则和设计模式,设计原则相对于设计模式来说更抽象些,贯穿于整个项目架构和项目编程中,是一个灵魂,设计模式的话,通俗一点说就是某个功能模块使用何种方式去实现。
一、单一职责原则
定义:
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,它规定一个类应该只有一个发生变化的原因。
通俗一点就是,一个类或者接口中只能存在功能相似程度比较高的方法,比如要绘制矩形、圆,也要显示矩形和圆,那么可以将绘制矩形和圆的实现定义在一个接口中,将显示矩形和圆的实现定义在另外一个接口中;而不能将绘制和显示定义在同一个接口中。
/** * Created by Administrator on 2017/10/25. * 绘制图形接口 */public interface DrawPicture { /** * 绘制矩形 */ void drawCircle(); /** * 绘制矩形 */ void drawRect();}
/** * Created by Administrator on 2017/10/25. * 显示图形接口 */public interface ShowPicture { /** * 显示圆形 */ void showCircle(); /** * 显示矩形 */ void showRect();}
public class Picture implements DrawPicture,ShowPicture{ @Override public void drawCircle() { } @Override public void drawRect() { } @Override public void showCircle() { } @Override public void showRect() { }}
这样子绘制图形或者显示图形有变动时对其他的并没有太多影响。
特点:
1、降低了类或者接口的复杂性,对类或者接口的职责有清晰明确定义;
2、提高了可读性;
3、提高可维护性;
4、降低变更引起的风险,接口改变只影戏相应的实现类,不影响其他类;
注意点:
1、接口一定要做到单一职责;
2、类的单一职责比较难以实现,尽量做到只有一个原因引起变化;
3、一个方法尽可能做一件事,能分解就分解,分解到原子级别;
适用范围:
接口、类、方法
二、里氏替换原则
定义:
所有引用基类的地方必须能透明的使用其子类对象。
需求:
玩家玩射击气球游戏,既能使用AK仿真气枪,也可以使用步枪或其他枪类射击气球。
/** * Created by Administrator on 2017/10/25. * 枪接口 */public interface IGun { /** * 射击方法 */ void fire();}
/** * Created by Administrator on 2017/10/25. * 枪的具体实现类 */public class AK47Gun implements IGun{ @Override public void fire() { System.out.println("AK47Gun--->开火"); }}
/** * Created by Administrator on 2017/10/25. * 枪的具体实现类 */public class USPGun implements IGun{ @Override public void fire() { System.out.println("USPGun--->开火"); }}
/** * Created by Administrator on 2017/10/25. */public class Play { private IGun iGun; public Play(IGun iGun){ this.iGun=iGun; } /** * 进攻方法 */ public void fire(){ iGun.fire(); }}
/** * Created by Administrator on 2017/10/25. * 用户类 */public class Client { public void playFire(){ IGun ak47Gun=new AK47Gun(); Play play=new Play(ak47Gun); play.fire(); IGun uspGun=new USPGun(); Play play1=new Play(uspGun); play1.fire(); }}
里氏替换原则的核心是继承,也是多态的体现,同样它的优缺点也是继承的优缺点;
优点:
1、代码共享:子类都拥有父类的方法和属性,将父类的代码共享给子类;
2、重用性:提供了代码的重用性,子类重用父类的代码;
3、扩展性:提高代码的可扩展性,子类可以随意扩展父类;
4、开放性:父类随意扩展,开放性随之增加;
缺点:
1、侵入性:子类强制继承或实现父类的方法和属性
2、灵活性:降低代码的灵活性,子类必须拥有父类的属性和方法,子类收到父类的约束,这是从子类的角度考虑;
3、耦合性:增强了耦合性,父类的属性和方法被修改时,还需要顾及其子类,可能会带来大量的重构,这是从父类考虑;
注意点:
1、父类方法返回值类型F,子类方法返回值类型S,里氏替换原则是S范围必须小于F范围;
2、父类、子类方法参数类型或者数量不同,如果要符合里氏替换原则要求的话,子类参数必须>=父类参数,即不能让子类自己定义的方法被调用;
3、如果想使用里氏替换原则,尽量避免让子类拥有自己单独的成员变量或者方法,如果子类个性多了,子类父类关系很难调和;
三、依赖倒置原则
定义:
高层模块不应该依赖于底层模块,二者都应该依赖于其抽象,抽象应该不依赖于细节,细节应该依赖于抽象。
问题由来:
类A直接依赖类B,假如要将类A改成依赖类C,则必须要通过修改类A的代码来达成;这种场景下,类A一般是高层模块,负责复制的业务逻辑;类B和类C是底层模块,负责基本的原子操作,假如修改类A,会给程序带来不必要的风险。
解决方案:
将类A修改为依赖接口I,类B和类C各自实现接口I,类A通过接口间接与类B或类C发生联系,则会大大降低修改类A的几率。
需求场景:
母亲给孩子讲故事
/** * Created by Administrator on 2017/10/26. * 读书接口 */public interface Reader { /** * 获取读书的类容 * @return 返回读书的类容 */ public String getReadContent();}
/** * Created by Administrator on 2017/10/26. * 读书接口的实现类 */public class NewsReader implements Reader{ @Override public String getReadContent() { return "妈妈在读新闻"; }}
/** * Created by Administrator on 2017/10/26. * 读书接口的实现类 */public class StoryBook implements Reader{ @Override public String getReadContent() { return "妈妈在读小说故事"; }}
/** * Created by Administrator on 2017/10/26. */public class Monther { private Reader reader; public Monther(Reader reader){ this.reader=reader; } public void iReader(){ String readContent = reader.getReadContent(); System.out.println("readContent-->"+readContent); }}
/** * Created by Administrator on 2017/10/26. */public class Client { public void iReader(){ Reader newsReader=new NewsReader(); Monther monther=new Monther(newsReader); monther.iReader(); Reader storyBook=new StoryBook(); Monther monther1=new Monther(storyBook); monther1.iReader(); }}
依赖倒置原则也是策略模式的体现;依赖倒置原则的本质就是通过接口或者抽象类,是各个类或者模块实现彼此独立,实现模块间松耦合。
依赖倒置原则好处:
1、减少了类之间的耦合;
2、提高系统的稳定性;
3、降低并发风险;
4、提高代码的可读性;
依赖倒置注入的实现:
1、构造方法依赖对象:通过构造函数参数声明依赖对象;
2、setter方法依赖对象:通过setter函数参数声明依赖对象;
3、接口注入依赖对象:在接口方法的参数中声明依赖对象;
注意点:
尽量不要覆盖方法,如果方法在抽象类中已经实现,子类不要覆盖。
四、接口隔离原则
定义:
1、建立单一的接口, 功能尽量细化, 不要建立臃肿的接口;
2、不需要的接口 ,客户端尽量不依赖其不需要的接口, 客户端需要什么接口就提供什么接口, 剔除不需要的接口, 对接口进行细化, 保持接口方法最少;
3、最小接口 : 类间的依赖关系应该建立在最小接口上, 细化接口;
接口隔离原则应遵循不能违反单一原则,这里说的不能违反单一原则指的是:接口隔离原则要求建立单一的接口,功能尽量细化,但是不能将业务一致或者相似的功能拆分成多个接口;但是和单一原则又有不同;
单一原则和接口隔离原则区别:
单一原则:注重职责,注重业务逻辑上的划分;
接口隔离原则:注重的是接口的方法尽量少;
特点:
1、接口尽量小:拆分接口,接口隔离的核心定义,不出现臃肿的接口,但是在拆分接口的时候需要注意接口小有限度,不能违反单一原则,不能将一个业务逻辑拆分成两个接口;
2、接口高内聚:提高接口、类、方法、模块的处理能力,减少对外交互,接口中尽量少用public修饰,对外公布的public方法越少,变更的风险就越小,有利于后期的维护;
3、定制服务:系统模块间的耦合需要有相互访问的接口,这里就需要为各个客户端的访问提供定制的服务接口,在提供接口的时候只需要提供访问者需要的接口,不需要的就不提供;
4、接口隔离限度:接口粒度越小,系统越灵活,但是同时使系统结构复杂,开发难度增加,降低了系统的可维护性,
原子接口划分原则:
接口模块对应的关系:一个接口只服务于一个子模块或业务逻辑;
方法压缩:通过业务逻辑,压缩接口中的public方法,减少接口的方法数量;
修改适配:尽量去修饰已经污染的接口,如果变的风险较大,采用适配器模式进行转换处理;
五、迪米特法则
定义:
也叫最少只是原则,一个对象应该对其他对象有最少的了解,即一个类对自己需要耦合或者调用的类知道的最少。
通俗一点就是将类B暴露给类A的方法封装,暴露的越少越好,类B高内聚,类A低耦合;所以在系统设计的时候,能用 private 就用private , 能用 protected 就用 protected, 能少用 public 就少用 public, 能加上 final 就加上 final;
优缺点:
优点:类间解耦, 弱耦合, 耦合降低, 复用率提高;
缺点:类间的耦合性太低, 会产生大量的中转或跳转类, 会导致系统的复杂性提高, 加大维护难度;
六、开闭原则
定义:
软件的实体 类, 模块, 函数 应该对扩展开放, 对修改关闭; 即 软件实体 应该 通过扩展实现变化, 不是通过 修改已有的代码实现变化;
1、利于测试 : 如果改变软件内容, 需要将所有的测试流程都执行一遍, 如 单元测试, 功能测试, 集成测试等, 如果只是扩展, 只单独测试扩展部分即可;
2、提高复用性 : 所有逻辑都从原子逻辑组合, 原子逻辑粒度越小, 复用性越大; 这样避免相同逻辑存在, 修改时需要修改多个此相同逻辑;
3、提高可维护性 : 维护一个类最好的方式是 扩展一个类, 而不是修改一个类, 如果需要修改需要读懂源码才能修改, 扩展的话只需要了解即可, 直接继承扩展;
- 面向对象六大基本原则
- 面向对象六大基本原则
- 面向对象六大基本原则
- 面向对象设计六大基本原则
- 面向对象的六大基本原则
- 面向对象的六大基本原则
- 面向对象设计的六大基本原则
- java面向对象程序设计的六大基本原则
- (Java)面向对象编程六大基本原则
- 面向对象设计的六大基本原则
- 面向对象设计六大基本原则-以Volley为例
- 面向对象设计六大基本原则-以Volley为例
- Java - 面向对象设计六大基本原则-以Volley为例
- 走向灵活的软件之路--面向对象六大基本原则
- 面向对象六大基本原则、设计模式、工程模式
- 深入理解面向对象——六大基本原则
- 面向对象设计基本原则
- 面向对象的基本原则:
- 高通sensor架构实例分析之一
- 实验5:树和二叉树的实验1
- GridView+轮播图
- iPhone X 为啥弃 TouchID?
- 构造随机数
- 面向对象六大基本原则
- 高通sensor架构实例分析之二(驱动代码结构)
- 二进制|什么是反射?
- 高通sensor架构实例分析之三(adsp上报数据详解、校准流程详解)
- 5404. 【NOIP2017提高A组模拟10.10】Graph
- vue-awesome-swiper
- JZOJ5419. 【NOIP2017提高A组集训10.24】筹备计划
- 各种软件安装包
- 所