开闭原则(OCP)
定义
开闭原则(Open-Closed Principle, OCP) :一个软件实体如类、模块和函数应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。 用抽象构建框架,用实现扩展细节。 优点:提高软件系统的可复用性和可维护性。
实现开闭原则的核心思想,就是面向抽象继承。
Golang Demo
package openclose
type CourseInterface interface {
GetID() int
GetName() string
GetPrice() float32
}
package openclose
type JavaCourse struct {
id int
name string
price float32
}
func NewJavaCourse(id int, name string, price float32) *JavaCourse {
return &JavaCourse{id: id, name: name, price: price}
}
func (j *JavaCourse) GetID() int {
return j.id
}
func (j *JavaCourse) GetName() string {
return j.name
}
func (j *JavaCourse) GetPrice() float32 {
return j.price
}
package openclose
type JavaDiscountCourse struct {
JavaCourse
}
func NewJavaDiscountCourse(ID int, name string, price float32) *JavaDiscountCourse {
return &JavaDiscountCourse{JavaCourse: *NewJavaCourse(ID, name, price)}
}
func (j *JavaDiscountCourse) GetOriginPrice() float32 {
return j.GetPrice()
}
func (j *JavaDiscountCourse) GetDiscountPrice() float32 {
return j.GetPrice() * 0.8
}
package openclose
import (
"testing"
)
func TestOpenClose(t *testing.T) {
course := NewJavaDiscountCourse(1, "JavaEE", 10)
t.Logf("\nid:%d,\n名称:%s,\n价格:%f,\n折后价格:%f\n", course.GetID(), course.GetName(), course.GetPrice(), course.GetDiscountPrice())
}
Java Demo
package tech.selinux.design.principle.openclose;
public interface ICourse {
Integer getID();
String getName();
Double getPrice();
}
package tech.selinux.design.principle.openclose;
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 ID;
}
@Override
public String getName() {
return Name;
}
@Override
public Double getPrice() {
return Price;
}
}
package tech.selinux.design.principle.openclose;
public class JavaDiscountCourse extends JavaCourse {
public JavaDiscountCourse(Integer id, String name, Double price) {
super(id, name, price);
}
public Double getOriginPrice() {
return super.getPrice() ;
}
public Double getDiscountPrice() {
return super.getPrice() * 0.8;
}
}
package tech.selinux.design.principle.openclose;
public class Test {
public static void main(String[] args) {
ICourse iCourse = new JavaDiscountCourse(96, "Java", 348d);
JavaDiscountCourse javaCourse = (JavaDiscountCourse) iCourse;
System.out.println(
"ID:"
+ javaCourse.getID()
+ " 名称:"
+ javaCourse.getName()
+ " 原价:"
+ javaCourse.getOriginPrice()
+ " 折后价格:"
+ javaCourse.getDiscountPrice()
+ "元");
}
}
UML
总结
从上面两个Demo 中,我们还能看出一个Java 和 Golang 的区别。Java中,虽然用子类示例化了接口,但是在使用子类的方法时,还是需要将接口转成子类,而Golang中没有这种要求。
补充另一个版本的Java/Scala Demo 以及源码解析
Java Demo_
Scala Demo
UML_
源码解析
Last updated