定义
一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。 强调的是用抽象构建框架,用实现扩展细节。
核心思想
面向抽象编程,因为抽象是稳定的。
理解
不改变原先的业务逻辑,新增的功能点通过重写复用的方法进行编程。
优点
提高软件系统的可复用性以及可维护性
简单需求说明
软件实体ICourse,以及它的实现JavaCource实现了基本功能,如需要额外的功能可以对JavaCourse进行扩展即继承来添加,
这样在不修改底层的ICourse和JavaCourse的前提下,做到功能的添加。即,越基层的模块影响范围越大,越高层的模块影响
范围较小,总体实现了对扩展开放,对修改关闭,这样就可以有效解决影响范围。
coding
v1 基类
接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.design.pattern.principle.openclose;
public interface ICourse {
Integer getId();
String getName();
Double getPrice(); }
|
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| package com.design.pattern.principle.openclose;
import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;
@AllArgsConstructor @NoArgsConstructor @Data public class JavaCourse implements ICourse {
private Integer id;
private String name;
private Double price; @Override public Integer getId() { return this.id; }
@Override public String getName() { return this.name; }
@Override public Double getPrice() { return this.price; } }
|
应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.design.pattern.principle;
import com.design.pattern.principle.openclose.ICourse; import com.design.pattern.principle.openclose.JavaCourse; import com.design.pattern.principle.openclose.JavaDiscountCourse; import lombok.extern.slf4j.Slf4j; import org.junit.Test;
@Slf4j public class OpencloseTest {
@Test public void testBase(){ ICourse javaCourse = new JavaCourse(100,"Java从入门到放弃",200d); log.info(String.format("课程id: %d,课程名: %s, 课程价格:%f", javaCourse.getId(), javaCourse.getName(), javaCourse.getPrice()) ); } }
|
v2
1
| 需求:打印出原价和折扣后的价格以及课程其他信息(接口不应该随意发生变化,面向接口编程)
|
接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package com.design.pattern.principle.openclose;
public interface ICourse {
Integer getId();
String getName();
Double getPrice(); }
|
实体类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.design.pattern.principle.openclose;
public class JavaDiscountCourse extends JavaCourse {
public JavaDiscountCourse(Integer id, String name, Double price) { super(id, name, price); }
@Override public Double getPrice() { return super.getPrice() * 0.8; }
public Double getOriginPrice(){ return super.getPrice(); }
}
|
应用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package com.design.pattern.principle;
import com.design.pattern.principle.openclose.ICourse; import com.design.pattern.principle.openclose.JavaCourse; import com.design.pattern.principle.openclose.JavaDiscountCourse; import lombok.extern.slf4j.Slf4j; import org.junit.Test;
@Slf4j public class OpencloseTest {
@Test public void testBase(){ ICourse javaCourse = new JavaCourse(100,"Java从入门到放弃",200d); log.info(String.format("课程id: %d,课程名: %s, 课程价格:%f", javaCourse.getId(), javaCourse.getName(), javaCourse.getPrice()) ); }
@Test public void testEx(){ ICourse javaCource = new JavaDiscountCourse(100,"java从入门到放弃",200d); log.info(String.format("课程id: %d,课程名: %s, 课程原价:%f,课程折扣价格:%f", javaCource.getId(), javaCource.getName(), ((JavaDiscountCourse) javaCource).getOriginPrice(), javaCource.getPrice()) ); }
}
|