1. 输入法皮肤扩展(抽象类实现)
场景:用户可为输入法更换不同皮肤(如默认皮肤、CSDN皮肤)。
实现:
- 抽象层:定义抽象类
AbstractSkin
,声明皮肤显示方法。 - 扩展:新增皮肤只需继承抽象类并实现方法,无需修改输入法主类。
// 抽象皮肤类
public abstract class AbstractSkin {
public abstract void display();
}
// 具体皮肤类
public class DefaultSkin extends AbstractSkin {
@Override
public void display() { System.out.println("默认皮肤"); }
}
public class CSDNSkin extends AbstractSkin {
@Override
public void display() { System.out.println("CSDN皮肤"); }
}
// 输入法类(依赖抽象)
public class SouGouInput {
private AbstractSkin skin;
public void setSkin(AbstractSkin skin) { this.skin = skin; }
public void display() { skin.display(); }
}
扩展性:新增TheodoreSkin
时,仅需编写新子类,调用setSkin()
即可生效。
2. 图形绘制系统(多态替代条件判断)
问题:原始代码通过if-else
判断图形类型,新增图形需修改核心逻辑(违反OCP)。
// 违反OCP的原始代码
class GraphicEditor {
void drawShape(Shape s) {
if (s.m_type == 1) drawRectangle(s);
else if (s.m_type == 2) drawCircle(s);
}
}
改进:抽象类Shape
定义draw()
方法,子类实现具体逻辑。
// 遵循OCP的改进代码
abstract class Shape { abstract void draw(); }
class Rectangle extends Shape {
@Override void draw() { System.out.println("绘制矩形"); }
}
class Triangle extends Shape {
@Override void draw() { System.out.println("绘制三角形"); }
}
// 调用方无需修改
class GraphicEditor {
void drawShape(Shape s) { s.draw(); }
}
优势:新增图形只需添加子类,无需改动GraphicEditor
。
3. 支付方式扩展(策略模式)
场景:支持微信、支付宝等支付方式,新增支付方式时无需修改核心逻辑。
实现:
- 接口定义:声明支付行为。
- 扩展:新增支付类实现接口,通过工厂动态创建。
// 支付接口
public interface Payment {
void pay();
}
// 具体支付类
public class WeChatPay implements Payment {
@Override public void pay() { System.out.println("微信支付"); }
}
// 支付工厂(扩展时新增工厂方法)
public class PaymentFactory {
public static Payment create(String type) {
if ("wechat".equals(type)) return new WeChatPay();
// 扩展支付宝:新增条件分支
else if ("alipay".equals(type)) return new AliPay();
return null;
}
}
扩展性:新增AliPay
类后,仅需扩展工厂逻辑,调用方代码不变。
4. 动物行为扩展(接口隔离)
场景:统一管理不同动物的共同行为(如eat()
),扩展行为时不影响原有逻辑。
// 动物接口
public interface Animal {
void eat();
}
// 具体动物类
public class Cat implements Animal {
@Override public void eat() { System.out.println("猫吃鱼"); }
// 新增行为(如sleep()):仅扩展当前类,不影响其他动物
public void sleep() { System.out.println("猫睡觉"); }
}
说明:新增行为通过扩展具体类实现,接口保持稳定。
5. 图形面积计算(从硬编码到抽象)
问题:原始代码通过instanceof
判断图形类型,新增图形需修改计算逻辑。
// 违反OCP的原始代码
double calculateArea(Object shape) {
if (shape instanceof Circle) { /* 计算圆面积 */ }
else if (shape instanceof Rectangle) { /* 计算矩形面积 */ }
}
改进:定义Shape
接口,子类实现计算逻辑。
// 遵循OCP的改进代码
interface Shape { double calculateArea(); }
class Circle implements Shape {
@Override double calculateArea() { return Math.PI * radius * radius; }
}
扩展性:新增Triangle
类实现接口,计算逻辑无需修改主类。
总结:开闭原则的核心实践
- 抽象化:通过接口或抽象类定义稳定框架。
- 多态扩展:新增功能通过实现子类完成。
- 设计模式结合:工厂、策略模式等增强扩展性。
- 降低耦合:调用方依赖抽象而非具体实现。
通过上述案例可见,开闭原则显著提升了代码的可维护性和扩展性,是构建灵活系统的基础。