引言:让我们重温经典,致敬经典
开放封闭原则:对扩展是开放的,对修改是关闭的
做到这个在刚开始的时候是不容易的,在刚开始是不会变化的,当发生变化的时候,我们应该创建抽象来隔离以后发生的同类变化。
举个栗子来解读上面这句话:
好比有个人,他刚开始会的技能只有唱歌,后来他又会了跳舞,再后来又会了写bug再后来又会了。。。此时我们应该把这个技能抽象出来
代码:
1 package com.dzf.designtest; 2 3 /** 4 * <desc> 5 * 开放封闭原则代码演示 6 * </desc> 7 * @author dingzf 8 * @date 2018/3/30 9 * @time 23:34 10 */ 11 public class OpenClosePrinciple { 12 public static void main(String[] args) { 13 //第一版 14 Person person1 = new Person(); 15 person1.show(); 16 //第二版违反了开放封闭原则 17 Person2 person2 = new Person2(); 18 person2.show(); 19 //改造,将变化的抽象出来,防止以后出现同样的变化 20 person3 person3 = new person3(); 21 person3.setSkill(new SkillImpl()); 22 person3.shwo(); 23 } 24 } 25 26 /** 27 * 刚开始类是这样的,第一版代码 28 */ 29 class Person{ 30 /** 31 * 展示会的技能 32 */ 33 public void show(){ 34 System.out.println("我会跳舞"); 35 } 36 } 37 38 /** 39 * 第二版代码,我们发现这个我们违反了开发封闭原则,我们就把变化的抽象出来 40 */ 41 class Person2{ 42 /** 43 * 展示会的技能 44 */ 45 public void show(){ 46 System.out.println("我会跳舞"); 47 System.out.println("我会唱歌"); 48 } 49 } 50 51 /** 52 * 第三版 53 */ 54 class person3{ 55 private Skill skill; 56 57 public Skill getSkill() { 58 return skill; 59 } 60 61 public void setSkill(Skill skill) { 62 this.skill = skill; 63 } 64 65 public void shwo(){ 66 if(skill!=null){ 67 skill.show(); 68 } 69 } 70 } 71 abstract class Skill{ 72 public abstract void show(); 73 } 74 class SkillImpl extends Skill{ 75 public void show(){ 76 System.out.println("我会跳舞"); 77 System.out.println("我会唱歌"); 78 System.out.println("我会写bug"); 79 } 80 }
依赖倒置原则:高层模块不能依赖低层模块,两个都应该依赖抽象,抽象不应该依赖细节,细节应该依赖抽象
解释下,这个主要是为了降低耦合性,上面这句说我们可以用我们常用的service层和dao层来说明,高层不应该依赖第层,是说service层不应该依赖dao层,而都依赖接口,我们一般都会定义service层的接口和dao层的接口。抽象不应该依赖细节,细节应该依赖抽象,就是说要针对接口编程不要针对实现编程,好比我们service要调用dao层,我们要依赖的是dao层接口,而不是dao层的实现类,我们针对的是对接口,而不是针对细节,这样做我们可以更好的扩展。
职责单一原则:说一个类应该只有一种引起它变化的原因。从子面上理解,就是就专注干一件事,其实这些都是为了低耦合的。
里氏替换原则:说子类型必须能够替换掉他们的父类型。正是由于这个原则,才使得使用父类型的模块无需修改的情况下就可以扩展。不然还谈什么开放封闭啊,依赖倒置啊。这个是基础。