软件设计七大原则之开闭原则

本文探讨了软件设计中的开闭原则,强调了通过抽象构建框架以提高软件的可复用性和可维护性。详细解释了抽象类的作用,以及如何在不修改原有代码的基础上,通过继承和重写来扩展功能。

定义:

        一个软件的实体 如类,模块和函数应该对扩展开放,对修改关闭。

优点:

        提高软件系统的可复用性及可维护性。

主要思想:

        开闭原则主要强调的是用抽象构建框架,用实现扩展细节,所以实现开闭原则的主要思想就是面向抽象编程而非面向实现编程。

抽象类:

        抽象类不能创建实例,它只能作为父类被继承。抽象类是从多个具体类中抽象出来的父类,它具有更高层次的抽象。从多个具有相同特征的类中抽象出一个抽象类,以这个抽象类作为其子类的模板,从而避免了子类的随意性。

使用抽象类原因:

        在面向对象程序设计中,抽象类主要用来进行类型隐藏。构造出一个固定的一组行为的抽象描述,但是这组行为却能够有任意个可能的具体实现方式。这个抽象描述就是抽象类,而这一组任意个可能的具体实现则表现为所有可能的派生类。模块可以操作一个抽象体。由于模块依赖于一个固定的抽象体,因此它可以是不允许修改的;同时,通过从这个抽象体派生,也可扩展此模块的行为功能。为了能够实现面向对象设计的一个最核心的原则OCP(Open-Closed Principle),抽象类是其中的关键所在。

举例:

下面我们通过代码实现更深入的了解一下开闭原则(以商品为例):

import java.math.BigDecimal;
/**
 * 先定义一个接口,用于获取商品信息
 */
public interface GoodsInterface {
    Integer getGoodsId();
    String getGoodsName();
    BigDecimal getGoodsPrice();
}

实现该接口

import java.math.BigDecimal;

public class GoodsImpl implements GoodsInterface {

    private Integer goodsId;
    private String goodsName;
    private BigDecimal goodsPrice;

    public GoodsImpl(Integer goodsId, String goodsName, BigDecimal goodsPrice) {
        this.goodsId = goodsId;
        this.goodsName = goodsName;
        this.goodsPrice = goodsPrice;
    }

    public Integer getGoodsId() {
        return this.goodsId;
    }

    public String getGoodsName() {
        return this.goodsName;
    }

    public BigDecimal getGoodsPrice() {
        return this.goodsPrice;
    }
}
import java.math.BigDecimal;
/**
 * 启动,查看商品信息
 */
public class Test {
    public static void main(String[] args) {
        GoodsInterface good = new GoodsImpl(1,"超级大西瓜",new BigDecimal("100"));
        System.out.println("名称:"+good.getGoodsName()+"--价格:"+good.getGoodsPrice());
    }
}

如果此时搞促销,商品需要打折出售,那么我该怎么做呢?上代码。

import java.math.BigDecimal;

public class GoodsPromotion extends GoodsImpl {
    /**
     * 继承父类的构造方法
     */
    public GoodsPromotion(Integer goodsId, String goodsName, BigDecimal goodsPrice) {
        super(goodsId, goodsName, goodsPrice);
    }
    /**
     * 重写价格信息
     */
    public BigDecimal originalPrice(){
        return super.getGoodsPrice();
    }
    public BigDecimal discountPrice(){
        return super.getGoodsPrice().multiply(new BigDecimal("0.8"));
    }
}

这样我们就可以通过重写来完成我们的新增需求,而不改变原有的代码。下面看测试结果

public class Test {
    public static void main(String[] args) {
        GoodsImpl good = new GoodsPromotion(1,"超级大西瓜",new BigDecimal("100"));
        GoodsPromotion goodsPromotion = (GoodsPromotion)good;
        System.out.println("名称:"+goodsPromotion.getGoodsName()+" 原价:"+goodsPromotion.originalPrice()+" 促销价:"+goodsPromotion.discountPrice());
    }
}

为了方便理解,帖上UML图,如下:

 

总结: 自己目前还没有完全理解开闭原则,所以以记录的方式加深自己的理解,望各位大佬能够指点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值