随笔 - 361,  文章 - 0,  评论 - 62,  阅读 - 160万

  以一个关于课程的例子展示开闭原则:

复制代码
/**
 * 定义课程接口
 */
public interface ICourse {
    String getName();  // 获取课程名称
    Double getPrice(); // 获取课程价格
    Integer getType(); // 获取课程类型
}

/**
 * 英语课程接口实现
 */
public class EnglishCourse implements ICourse {

    private String name;
    private Double price;
    private Integer type;

    public EnglishCourse(String name, Double price, Integer type) {
        this.name = name;
        this.price = price;
        this.type = type;
    }

    @Override
    public String getName() {
        return null;
    }

    @Override
    public Double getPrice() {
        return null;
    }

    @Override
    public Integer getType() {
        return null;
    }
}

// 测试
public class Main {
    public static void main(String[] args) {
        ICourse course = new EnglishCourse("小学英语", 199D, "Mr.Zhang");
        System.out.println(
                "课程名字:"+course.getName() + " " +
                "课程价格:"+course.getPrice() + " " +
                "课程作者:"+course.getAuthor()
        );
    }
}
复制代码

  项目上线,课程正常销售,但是我们产品需要做些活动来促进销售,比如:打折。那么问题来了:打折这一动作就是一个变化,而我们要做的就是拥抱变化,现在开始考虑如何解决这个问题,可以考虑下面三种方案:

  1、修改接口

  在之前的课程接口中添加一个方法 getSalePrice() 专门用来获取打折后的价格;

  如果这样修改就会产生两个问题,所以此方案否定

  • ICourse 接口不应该被经常修改,否则接口作为契约的作用就失去了
  • 并不是所有的课程都需要打折,加入还有语文课,数学课等都实现了这一接口,但是只有英语课打折,与实际业务不符
复制代码
public interface ICourse {

    // 获取课程名称
    String getName();

    // 获取课程价格
    Double getPrice();

    // 获取课程类型
    String getAuthor();

    // 新增:打折接口
    Double getSalePrice();
}
复制代码

  2、修改实现类

  在接口实现里直接修改 getPrice()方法,此方法会导致获取原价出问题;或添加获取打折的接口 getSalePrice(),这样就会导致获取价格的方法存在两个,所以这个方案也否定。

  3、通过扩展实现变化

  直接添加一个子类 SaleEnglishCourse ,重写 getPrice()方法,这个方案对源代码没有影响,符合开闭原则,所以是可执行的方案,代码如下,代码如下:

复制代码
public class SaleEnglishCourse extends EnglishCourse {

    public SaleEnglishCourse(String name, Double price, String author) {
        super(name, price, author);
    }

    @Override
    public Double getPrice() {
        return super.getPrice() * 0.85;
    }
}
复制代码

  综上所述,如果采用第三种,即开闭原则,以后再来个语文课程,数学课程等等的价格变动都可以采用此方案,维护性极高而且也很灵活。

posted on   kosamino  阅读(3144)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2019-03-26 Git常用命令及场景

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示