2.开闭原则

一、定义

  一个软件实体应当对扩展开放,对修改关闭

  也就是说在设计 一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即在不修改源代码的情况下改变这个模块的行为。

二、开闭原则分析

  (1)开闭原则是面向对象设计中最重要的原则之一。

  在开闭原则的定义中,软件实体可以指一个软件模块、一个由多个类组成的局部结构或一个独立的类。

  (2)抽象化是开闭原则的关键。抽象化就是将一个类(实体)里面或者多个类里面公共的东西抽取出来,抽象的好处就是稳定的、可靠的、不容易发生改变的。

  开闭原则还可以通过一个更加具体的可变性封装原则 来描述,对可变性封装原则要求找到系统的可变因素并将其封装起来。

与信息隐藏原则有些类似,信息隐藏原则有两个:一个是隐藏复杂的东西,另一个是隐藏可变的东西。

三、示例1

1.存在问题

在这里插入图片描述
  (1)原始的设计方案就是,在登录界面希望用一个圆形按钮。 处理方法就是在 LoginForm 类里面包含了一个 CircleButton 类;然后 LoginForm 类用一个 display() 显示出来。

  (2)但是这样处理问题就出现了,如果用户要求使用其他类型的按钮,比如把圆形的改为矩形的,那要如何处理。如果按照之前的思路就是直接将 CircleButton 类改为 RectangleButton 类,如下图
在这里插入图片描述

2.开闭原则重构

  按照前面的方法,那么它违背了开闭原则。接下来就用开闭原则进行重构。

  (1)解决问题的思路:抽象化是开闭原则的关键,开闭原则要将可变的东西进行封装,将可变的东西进行封装变成稳定东西。

  (2)找出可变点,在这里可变的就是按钮的形状,所以需要将它稳定下来,也就是进行抽象化,封装。

  如果需求发生改变,要使用其他类型的按钮,只需要继承 AbstractButton 类就行。

如下图

在这里插入图片描述
在这里插入图片描述

  (3)还有一个问题:display() 显示 LoginForm 的时候按钮从哪里取呢,按钮的形状是变化的,这时候要额外增加一个文件(config.xml)。config.xml 文件里面增加一个节点叫做 < className >,在这个节点里标注出来 LoginForm 使用的是哪种类型的按钮。

  这里也起到了一个隔离的作用,把变化的东西移到第三方的配置文件里面,在配置文件里指出使用的是哪种。

  当 LoginForm 调用 display() 时,display() 可以读取配置文件进行初始化。

  如果需求发生改变,打开配置文件,将按钮的名称改好就可以,这样也是不修改源代码的。

在这里插入图片描述

  这里就是将可变的与不可变的东西进行了分离。就达到了对扩展是开放的,对修改是封闭的,满足了开闭原则。

四、示例2

  一般做一个 C/S 系统时,将系统分为两个模块,Client(客户端) 和 Server (服务端),Client 通常是调用 Server 提供的服务来满足业务要求。如下图
在这里插入图片描述

1.存在问题

  上面是一般传统的做法,但是这个做法也是有问题的,当需求发生变化时,要修改源代码。
在这里插入图片描述

2.重构

  (1)解决思路:在 Client 和 Server 中间增加一个抽象的东西,也就是接口(interface),叫做 Client Interface。顾名思义 Client Interface 就是面向 Client 的,为 Client 提供的接口。

  重构的思路就是在两个具体的、不稳定的类中间增加了一个抽象的、稳定的东西,它可以是抽象类,也可以是接口。再次强调抽象的东西是稳定的可靠的。

  (2)重构图如下:

在这里插入图片描述
在这里插入图片描述

五、总结

  在这两个例子中,其实就是在两个不稳定的、具体的类中间,增加一个抽象的、稳定的类;当需求发生变化时,就继承抽象类,从而达到不修改源代码,增加多分支的要求。

  这个就像是生活中的案例,电器是多种多样的,它们正常运行需要接通电源。这时候,我们就需要在供电所和电器之间增加一个统一的接口(插口),支持多种电器插到电源接口正常运行,而不需要每增加一种电器就要求供电所修改设置。

  这个接口同时也将电器和供电所隔离开来了。

在这里插入图片描述

在这里插入图片描述

  抽象化是开闭原则的关键

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值