设计模式|六大原则之开闭原则 实验
原理
- 定义:
- 优点:
网上随便一找都有
案例演示
课程购买的例子
抽象课程
定义一个接口ICourse.java
package com.dsdj.design.principle.openclose;
/**
* @ClassName ICourse
* @Description TODO
* @Author ChenLiLin
* @Date 2018/10/8 下午8:35
* @Version 1.0
**/
public interface ICourse {
Long getId();
Double getPrice();
String getName();
}
课程类MathCourse.java
package com.dsdj.design.principle.openclose;
/**
* @ClassName MathCourse
* @Description TODO
* @Author dsdj
* @Date 2018/10/8 下午8:36
* @Version 1.0
**/
public class MathCourse implements ICourse {
private String name;
private Double price;
private Long id;
public MathCourse(String name, Double price, Long id) {
this.name = name;
this.price = price;
this.id = id;
}
public Long getId() {
return this.id = id;
}
public Double getPrice() {
return this.price = price;
}
public String getName() {
return this.name = name;
}
@Override
public String toString() {
return "MathCourse{" +
"name='" + name + '\'' +
", price=" + price +
", id=" + id +
'}';
}
}
测试类Test.java
package com.dsdj.design.principle.openclose;
/**
* @ClassName Test
* @Description TODO
* @Author ChenLiLin
* @Date 2018/10/8 下午8:33
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
ICourse iCourse = new MathCourse("高数", 23.3d, 123l);
System.out.println(iCourse);
}
}
上面的代码是一个很简单的抽象。
下面有个新的需求
有了优惠活动需要对价格进行打折;
所以需要提供一个方法获取折后价格
分析:有两个思路
第一、修改MathCourse.java 添加一段代码
public interface ICourse {
// ..原来的代码省略
/**
* 新增抽象方法
* @return
*/
Double getDiscount();
}
这个方法可以实现,但我们发现问题了。
- 如果我们修改了这个接口,那么该接口所有的实现类都需要修改。
- 破坏了底层的代码(打折活动只是一时的)
以上不符合开闭原则的
因此我们进行如下的设计
新建一个类继承MathCourse类
package com.dsdj.design.principle.openclose;
/**
* @ClassName DiscountMathCourse
* @Description TODO
* @Author dsdj
* @Date 2018/10/8 下午11:35
* @Version 1.0
**/
public class DiscountMathCourse extends MathCourse {
public DiscountMathCourse(String name, Double price, Long id) {
super(name, price, id);
}
public Double getDiscountPrice(){
// 相关的业务代码
return super.getPrice()*0.5;
}
}
测试类
package com.dsdj.design.principle.openclose;
/**
* @ClassName Test
* @Description TODO
* @Author ChenLiLin
* @Date 2018/10/8 下午8:33
* @Version 1.0
**/
public class Test {
public static void main(String[] args) {
ICourse iCourse = new DiscountMathCourse("高数", 23.3d, 123l);
System.out.println(iCourse);
// 折扣功能
DiscountMathCourse discountMathCourse = (DiscountMathCourse) iCourse;
System.out.println("折扣价"+discountMathCourse.getDiscountPrice());
System.out.println("原价"+discountMathCourse.getPrice());
}
}
输出
总结
- 当我们的接口有很多方法,但实现类有比较复杂,修改接口有很大的风险。这种情况下我们可以继承一个基类继续扩展。
- 越底层的模块改动影响大,越高层的模块改动影响小,所以我们在面向对象开发的过程中要善于使用开闭原则。
- 开闭原则提高了复用性、可维护性。