- 开闭原则
定义: 一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
用抽象构建框架,用实现扩展细节
优点:提高软件系统的可复用性及可维护性。
当代码需要额外扩展或者修改定制专有的功能时,应该提供一种抽象来扩展功能 而不是修改原。
这里假设设计一个 课程类 实现 课程 的 Id 价格 名字的查询。
接口 和接口的实现类
//接口
public interface ICourse {
Integer getId();
String getName();
Double getPrice();
}
package com.gelly.design.principle.opencolse;
//实现类
public class JavaCourse implements ICourse {
private Integer Id;
private String name;
private Double price;
public JavaCourse(Integer id,String name,Double price){
this.Id =id;
this.name =name;
this.price =price;
}
@Override
public Integer getId() {
return this.Id;
}
@Override
public String getName() {
return this.name;
}
@Override
public Double getPrice() {
return this.price;
}
}
public static void main(String[] args) {
ICourse icourse = new JavaCourse(123,"java课程",20.0);
System.out.println("course id" + javacourse.getId() +"课程 名" +javacourse.getName()+javacourse.getDiscountPrice() + "课程价格:" + javacourse.getPrice());
}
以上是个很简单 的实现一个基本的 记录java 课程信息的类
但是 如果领导 像你提出要求 课程要打折 每到多少要满减怎么办。这一定难不倒你 于是你立马 就在接口里 添加上抽象方法 在实现里完成了 如果 这样频繁修改原有接口 原有的代码 可能导致 Bug的出现和不稳定的因素。
public interface ICourse {
Integer getId();
String getName();
Double getPrice();
Double getDiscountPrice();
}
public class JavaCourse implements ICourse {
@Override
public Double getDiscountPrice() {
return this.price;
}
}
所以怎么办呢 既能新增 功能 又能 不改变自己 其实很简单 那就找个 小弟 继承自己呗 小弟有自己的业务 。
//继承老大的业务
public class JavaDiscountCourse extends JavaCourse {
//直接调用老大 的 构造器
public JavaDiscountCourse(Integer id,String name,Double price){
super(id,name,price);
}
//这个属于自己独有的 业务
public Double getDiscountPrice() {
return super.getPrice() * 0.8 ;
}
public Double getOrigianPrice(){
return super.getPrice();
}
}
那该怎么初始化呢
public class Test {
public static void main(String[] args) {
// 这里就变成 new 继承者的构造器 JavaDiscountCourse
ICourse icourse = new JavaDiscountCourse(123,"java课程",20.0);
//由于是 使用ICourse 申明的引用 所以 javacourse.getDiscountPrice 是调用不了的 需要强制转型
JavaDiscountCourse javacourse = (JavaDiscountCourse)icourse;
System.out.println("course id" + javacourse.getId() +"课程 名" +javacourse.getName() +"java courese 打折价格"+javacourse.getDiscountPrice() + "课程价格:" + javacourse.getPrice());
}
}
这样就符合 开闭原则了,是不是很简单。
假设 MVC 架构中 上层是Controller 层 调用了Dao层 的模块A 模块A被很多地方引用了 改变了A模块就会 影响其他很多模块对A的调用(越低层次 基础 的模块 改动 影响的范围越广)
开闭原则,提高复用性,提高了可维护性(Spring AOP里 也是类似的 并不是通过修改Spring 源码 而是通过 扩展 重写Spring 提供的接口来 实现自己的功能)
当然说了那么多 你也可以 自由自在 我行我素 的不管 什么 开闭原则 写出惊天地泣鬼神 傲视群雄 的代码。