python 开闭原则_软件设计原则之开闭原则(Open-Closed Principle)

定义

类应该对扩展开放,对修改关闭。用抽象构建框架,用实现扩展细节。

我们的目标是允许类容易扩展,在不修改现有代码的情况下,就可搭配新的行为。如能实现这样的目标,有什么好处呢?这样的设计具有弹性可以应对改变,可以接受新的功能来应对改变的需求。

主要特征

对于扩展是开放的,这意味着模块的行为是可以扩展的。当应用的需求改变时,我们可以对模块进行扩展,使其具有满足那些改变的新行为。

对于修改是关闭的,这意味着对模块行为进行扩展时,不必改动模块的源代码或者二进制代码。

典型场景

在Java设计模式中,装饰者模式是一个很好的例子,完全遵循开放-关闭原则。

代码讲解

这里先以一个简单的例子讲解开放-关闭原则。

第一版需求:首先抽象出一个课程接口,然后Java,Python,UI等的课程来实现这个接口,打印出相关的课程信息。

定义一个接口Course:

public interface Course {

/**

* 课程Id

* @return

*/

Integer getId();

/**

* 课程名称

* @return

*/

String getName();

/**

* 课程价格

* @return

*/

Double getPrice();

}

定义一个接口Course的实现类JavaCourse:

public class JavaCourse implements Course {

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;

}

@Override

public String toString() {

return "JavaCourse{" + "id=" + id + ", name='" + name + '\'' + ", price=" + price + '}';

}

}

定义测试类:

public class Test {

public static void main(String[] args) {

Course javaCourse = new JavaCourse(1, "Java课程", 100d);

System.out.println(javaCourse);

}

}

打印出如下信息:

JavaCourse{id=1, name='Java课程', price=100.0}

上面对应的类图如下:

第二版需求:这个时候又来了一个需求,Java课程由于做活动,打8折,这个时候应该如何实现呢?

有如下几种实现方式:

1.在接口Course中,增加打折的方法getDiscountPrice(),如下:

Double getDisCountPrice();

这样JavaCourse实现这个方法即可。

2.直接在JavaCourse类中的getPrice方法中,直接将price*0.8。

这两种方式虽然实现起来很快,但是在应对需求变化时,是明显不足的。比如:

要求不同价格的折扣粒度不同

要求显示原来的价格

等等。

这个时候我们可以定义个折扣类来继承自JavaCourse,来实现对价格打折的支持,如下:

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;

}

}

然后修改测试类,如下:

Course javaCourse = new JavaDiscountCourse(1, "Java课程", 100d);

System.out.println("课程Id: " + javaCourse.getId() + ", 课程名称: " + javaCourse.getName() + ", 课程价格: " + javaCourse.getPrice());

输出如下:

课程Id: 1, 课程名称: Java课程, 课程价格: 80.0

这个时候有个问题,无法获取到原价,我们可以在JavaDiscountCourse增加获取原价的方法,如下:

public Double getOriginPrice() {

return super.getPrice();

}

修改测试类,如下:

Course course = new JavaDiscountCourse(1, "Java课程", 100d);

JavaDiscountCourse javaCourse = (JavaDiscountCourse) course;

System.out.println("课程Id: " + javaCourse.getId() + ", 课程名称: " + javaCourse.getName() + "课程原价:" + javaCourse.getOriginPrice() + ", 课程价格: " + javaCourse.getPrice());

这时我们的类图如下:

到此,我们的程序就修改完成了,而且不会对之前的代码有任何影响,这也就是开始提到的开放-关闭原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值