github地址:https://github.com/1711680493
如需了解更多设计模式,请进入我的设计模式专栏
开闭原则
软件应该对扩展开放,对修改关闭
当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求
作用
- 对软件测试的影响
- 软件遵守开闭原则的话,测试时只需要对扩展的代码进行测试就可以了,
- 因为原有的测试代码仍然能够正常运行
- 可以提高代码的可复用性
- 粒度越小,被复用的可能性就越大;在面向对象的程序设计中,
- 根据原子核抽象编程可以提高代码的可复用性
- 可以提高软件的可维护性
- 遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护
实现
可通过"抽象约束","封装变化",来实现开闭原则,即通过接口或者抽象类为软件实体,定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中
抽象约束
- 通过接口或抽象类对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法
- 参数类型,引用对象尽量使用接口/抽象类,而不是实现类
- 抽象层尽量保持稳定,一旦确定就不要修改
封装变化
找出预计有变化或不稳定的点,为这些变化点创建稳定的接口
例子:
开闭原则是对 扩展 开放,对 修改 关闭.
通过面向对象的特性我们就可以轻松实现扩展
例如我们有一类-衣服,品牌为X1的,我们启动类(主角),有穿衣功能,提供一件衣服就可以穿上(使用)
这个时候如果我们想要换一个品牌的衣服,我们该怎么做?
我们可以直接修改X1Clothes的 pingpai,但是这样就违反了开闭原则了,而且如果另一个地方需要这个pingpai怎么办?
这个时候我们可以创建一个接口,为衣服,提供一个方法用于获取当前pingpai,并且穿衣服的参数改成接口
代码如下
/** * 开闭原则. * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a> * @version 1.0 */ public class OpenClose { public static void main(String[] args) { chuanyi(new X1Clothes()); } // 穿衣 public static void chuanyi(Clothes clothes) { System.out.println(clothes.getPingpai()); } } // 衣服 interface Clothes { // 获取品牌 String getPingpai(); } /** * X1品牌的衣服 * @author Shendi <a href='tencent://AddContact/?fromId=45&fromSubId=1&subcmd=all&uin=1711680493'>QQ</a> * @version 1.0 */ class X1Clothes implements Clothes { // 品牌 String pingpai = "X1"; @Override public String getPingpai() { return pingpai; } }
这个时候是不是就满足开闭原则了呢?
当我们需要新增一个品牌的衣服只需要新增一个类(对扩展开放)
并且不用修改源类(对修改关闭)
总结
开闭原则是其他原则的基础,也是最重要的原则,我们写程序的时候尽量满足开闭原则.
对扩展开放,对修改关闭.