0103_开闭原则
定义:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭
场景
这里还上一篇【单一职责原则】中人类对象为例,人类属性有年龄、名称,动作有吃饭、行走、唱歌、跳舞、飞行等。现在需要增加跑步、跳远等运动员具备的技能。
反例
/**
* 人类类
*
*/
public class Human {
// 年龄属性
private int age;
// 姓名属性
private String name;
/**
* 构造方法
* @param age 年龄
* @param name 姓名
*/
public Human(int age, String name) {
this.age = age;
this.name = name;
}
/**
* 吃饭方法 - 基本生存行为
*/
public void eat() {
System.out.println("人类在吃饭");
}
/**
* 行走方法 - 基本移动行为
*/
public void walk() {
System.out.println("人类在行走");
}
/**
* 唱歌方法 - 艺术家行为
*/
public void sing() {
System.out.println("人类在唱歌");
}
/**
* 跳舞方法 - 艺术家行为
*/
public void dance() {
System.out.println("人类在跳舞");
}
/**
* 跑步方法 - 运动员
*/
public void run() {
System.out.println(this.name + "在跑步");
}
/**
* 跳远方法 - 运动员
*/
public void jump() {
System.out.println(this.name + "在跳远");
}
/**
* 飞行方法 - 特殊能力行为
* 注意:这个方法的存在说明了该类职责过多,因为不是所有人类都能飞行
* 应该将特殊能力提取到子类或接口中实现
*/
public void fly() {
if ("超人".equals(this.name)) {
System.out.println(this.name + "正在飞行");
} else {
System.out.println("只有超人才能飞行");
}
}
}
在反例中,Human类承担了过多的职责,现在需要增加跑步、跳远等动作,需要修改Human类,可能会影响其它引用类的逻辑。
正例

BaseHuman类
- 职责:只处理人类基本属性和基本生存行为
- 稳定性高:这些是所有人共有的基本特征和行为
- 易于扩展:可作为其他人类类型的基类
public class BaseHuman {
// 年龄属性
private int age;
// 姓名属性
private String name;
public BaseHuman(int age, String name) {
this.age = age;
this.name = name;
}
/**
* 获取姓名
* @return 姓名
*/
public String getName() {
return name;
}
/**
* 吃饭方法
*/
public void eat() {
System.out.println(getName() + "在吃饭");
}
/**
* 行走方法
*/
public void walk() {
System.out.println(getName() + "在行走");
}
}
SuperHuman类
- 职责:专门处理超人的特殊能力
- 隔离变化:特殊能力的修改不会影响普通人类
- 清晰性:明确表示这是特殊能力,不是普通人类行为
public class SuperHuman extends BaseHuman {
public SuperHuman(int age, String name) {
super(age, name);
}
/**
* 飞行方法
*/
public void fly() {
System.out.println(getName() + "正在飞行");
}
}
ArtistHuman类
- 职责:专门处理艺术相关的行为
- 遵循开闭原则:可以独立修改艺术行为而不影响其他类
- 可扩展性:可轻松添加新的艺术行为方法
public class ArtistHuman extends BaseHuman {
public ArtistHuman(int age, String name) {
super(age, name);
}
/**
* 唱歌方法
*/
public void sing() {
System.out.println(getName() + "在唱歌");
}
/**
* 跳舞方法
*/
public void dance() {
System.out.println(getName() + "在跳舞");
}
}
AthleteHuman类
- 职责:处理运动员特有的行为
- 遵循开闭原则:可以独立修改运动员行为而不影响其他类
- 可扩展性:可轻松添加新的运动员行为方法
public class AthleteHuman extends BaseHuman {
public AthleteHuman(int age, String name) {
super(age, name);
}
/**
* 跑步方法
*/
public void run() {
System.out.println(getName() + "在跑步");
}
/**
* 跳远方法
*/
public void jump() {
System.out.println(getName() + "在跳远");
}
}
总结
- 稳定与变化的分离
- 将稳定不变的基础属性(年龄、姓名)和核心行为(吃饭、行走)封装在BaseHuman
- 将可能变化的扩展行为(艺术、运动、超能力)分离到独立子类
- 扩展而非修改
- 新增运动功能时创建AthleteHuman类而非修改BaseHuman
- 每种特殊能力都有专属类实现,互不干扰
本方案通过经典的继承体系,既满足了开闭原则的要求,又保持了代码的简单直观,特别适合中等复杂度的业务场景。当系统行为维度超过5个时,建议升级为接口组合模式以获得更大灵活性。

浙公网安备 33010602011771号