java设计模式之开闭原则使用举例

发布于:2025-08-13 ⋅ 阅读:(13) ⋅ 点赞:(0)

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类实现接口,计算逻辑无需修改主类。


总结:开闭原则的核心实践

  1. 抽象化:通过接口或抽象类定义稳定框架。
  2. 多态扩展:新增功能通过实现子类完成。
  3. 设计模式结合:工厂、策略模式等增强扩展性。
  4. 降低耦合:调用方依赖抽象而非具体实现。
    通过上述案例可见,开闭原则显著提升了代码的可维护性和扩展性,是构建灵活系统的基础。