JAVA 开发 六大原则
1、六大原则
依赖倒置原则
2、依赖倒置原则
1、依赖倒置原则 开发的过程中 高层模块不应该依赖于底层模块,二者都应该依赖于抽象或者接口,抽象不应该依赖于细节,细节应该依赖于抽象 细节就是我们的接口实现类或者抽象类的继承类的一个方法 2、生活中的一个例子 比如说一个皇帝有好多的大臣,皇帝要把国家治理好需要依赖大臣去办事。皇帝是高层、太监是底层。 皇帝有什么旨意的时候一般都会让一个太监去传旨,一般不会皇帝直接去都大臣哪里去说安排任务一般都是传旨。 皇帝和太监之间建立直接的关系。皇帝制订好一个规则(接口),太监对皇帝暴露一个方法,方法里面有一个接口(规则),实际执行的时候传的是接口的实现类。 皇帝调用太监的方法,传接口实现类就是让某个大臣去干什么事。 3、依赖导致和maven的依赖有类似 facade模块被provider和consumer模块依赖。 接口实现类之间通过太监之间进行依赖,不直接某个具体的实现类。
2.1 举例
落实到代码中就是类似于策略模式,Controller 调用接口实现类时,不直接调用某个接口的实现类,而是通过中间层。
这里的细节可以理解成 策略类对外的一个方法
3、开闭原则
开闭原则 就是对已经有的类、函数、接口可以去扩展继承的方式 不要去修改原有的类、函数、接口 比如说项目中的高级开发写了一些个通用的方法、让不同的部门使用,如果不符合需求就不要在原来的上改了 继承就好,如果一个需求烂了就不会烂一块
3.1 代码举例
/** * 这里学习开闭原则,我们又一个新的需求需要设置𝝿的精度更大点 * 我们这里没有修改原有的逻辑,通过继承扩展了自己的需求 * */ @Component public class CalculationAreaExt extends CalculationArea{ private final static double 𝝿 = 3.1415916; //这里遵循了里氏替换原则,结果更严格 @Override public double circular(double r) { return 𝝿 * r * r; } }
4、里氏替换原则
/** * 1、里氏替换原则定义 * 继承必须确保超类所拥有的性质在子类中仍然成立 * 里氏替换原则主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中蕴含的原理。 * 父类的行为子类中依然可以具有,或者属性页可以使用。这时候才考虑继承 * 如果父类的行为子类中不适用,或者属性不使用等这时候不用使用继承 * 明确了什么时候用继承,什么时候不用继承 * 2、里氏替换原则的作用 * 1>里氏替换原则是实现开闭原则的重要方式之一。 * 即遵循了里氏替换原则也就是遵循了开闭原则 * 2>它克服了继承中重写父类造成的可复用性变差的缺点 * 即子类中按照里氏替换原则重写了子类的方法后,复用性依然存在,并且复用性可能变的更好 * 3>它是动作正确性的保证,即类的扩展不会给已有的系统引入新的错误,降低了代码出错的可能性 * 因为里氏替换原则要求重写的方法返回或者输入要求更严格最起码不必父类调用方法的结果更差。 * 4>加强程序的健壮性,同时变更时可以做到非常好的兼容性,提高程序的维护性,可扩展性,降低需求变更时引入的风险 * * 3、里氏替换原则要遵守的规则 * 子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写非抽像方法。 * * 1>子类可以实现父类的抽像方法,但尽量不要覆盖父类的非抽像方法 * 2>子类可以增加自己的特有方法 * 3>当子类的方法重载父类的方法时,方法的前置条件(即方法的入参)要比父类的方法更宽松 * 4>当子类的方法实现父类的方法时(重写/重载或实现抽像方法时),方法的后置条件(返回值或者输出)要比父类更严格或者相等 * 意思是父类和子类调用同样的方法,在参数一样的情况下,子类调用的结果应该比父类更严格或者相等 * */
4.1 代码举例
public class Bird { double flySpeed; public double getFlySpeed() { return flySpeed; } public void setFlySpeed(double flySpeed) { this.flySpeed = flySpeed; } public double getFlyTime(double distance){ return distance / flySpeed; } } /** * 燕子 */ public class Swallow extends Bird{ } /** * 几维鸟,不会飞 */ public class BrownKiwi extends Bird{ @Override public void setFlySpeed(double flySpeed) { flySpeed = 0; } } @RestController public class BirdController { @RequestMapping("/swallowFly") public String swallowFly(){ Bird bird = new Swallow(); bird.setFlySpeed(120); return "飞行300公里,燕子将飞行"+bird.getFlyTime(300)+"小时"; } @RequestMapping("/brownKiwiFly") public String brownKiwiFly(){ Bird bird = new BrownKiwi(); bird.setFlySpeed(120); //这里的结果是Infinity(无穷)小时 这里说明了几维鸟继承鸟 是不合理的 return "飞行300公里,几维鸟将飞行"+bird.getFlyTime(300)+"小时"; } @RequestMapping("/birdFly") public String birdFly(){ Bird bird = new Bird(); bird.setFlySpeed(120); return "飞行300公里,鸟将飞行"+bird.getFlyTime(300)+"小时"; } } 测试发现bird和swallow 飞是是正确的,几维鸟飞是结果是无穷大显然不合理的,由此发现该继承也是不合理的。