开发原则一:开闭原则OCP

前言

“需求总是变化”、“世界上没有一个软件是不变的”。这里投射出的意思是:需求总是变化的, 可是对于软件设计者来说, 如何才能做到不对原有系统修改的前提下, 实现灵活的扩展. 这就是开闭原则要实现的.
我们在设计系统的时候, 不可能设想一次性把需求确定后, 后面就不改变了.这不科学也不现实的. 既然需求是一定会变化的, 那么我们要如何优雅的面对这种变化呢? 如何设计可以使软件相对容易修改, 不至于需求一变, 就要把整个程序推到重来?
在这里插入图片描述

开闭原则的定义

开闭原则的定义是:“软件实体(类、模块、函数等)应该对扩展开放,对修改关闭”。简单来说,这个原则要求我们设计和编写的代码在需要进行增加新功能时,应该通过扩展已有的代码来实现,而不是直接修改已有的代码。

开闭原则的目标

开闭原则的目标是达到代码的可维护性和可扩展性。当我们的系统需要新增功能或者进行修改时,如果能保持原有的代码尽量不变,只是增加新的代码或者进行部分修改,那么就可以最大限度地减少出错的可能性,并且降低了对整个系统的影响。

开闭原则为什么这么重要

开闭原则的重要性在于以下几个方面:
可维护性:当需求发生变化时,如果一个系统符合开闭原则,我们只需要扩展已有的代码,而不是修改已有的代码。这样可以最大限度地减少对现有功能的影响,降低引入新问题的风险,提高代码的可维护性。
可复用性:符合开闭原则的代码具有良好的封装性和抽象性,可以更容易地被其他模块或系统所复用。我们可以通过扩展已有的代码来创建新的实现,而不是重复编写相似的代码。这不仅提高了代码的复用性,还减少了代码冗余,使系统更加灵活和可扩展。
可测试性:符合开闭原则的代码更容易进行单元测试和集成测试。由于扩展是通过添加新的代码而不是修改已有的代码实现的,我们可以针对新增的功能编写新的测试用例,而不影响原有的测试。这样能够更好地保证代码质量和稳定性。
可扩展性:开闭原则强调通过扩展来满足新的需求,这使得系统在面对未来的变化时更加容易适应和扩展。我们可以通过添加新的代码模块或类来引入新的功能,而不会影响到已有的功能。这样可以保持系统的灵活性,减少重构的需要,降低维护成本。
总之,开闭原则是一种设计思想和指导原则,它能够帮助我们构建出易于扩展、可维护和高质量的软件系统。遵循开闭原则能够提升软件的生命周期价值,降低系统的复杂度,并带来更好的开发和维护体验。

开闭原则的实践

1.抽象约束

第一,通过接口或者抽象类约束扩展,对扩展进行边界限定,不允许出现在接口或抽象类中不存在的public方法;
第二,参数类型、引用对象尽量使用接口或者抽象类,而不是实现类;
第三,抽象层尽量保持稳定,一旦确定即不允许修改。

2.元数据(metadata)控制模块行为

元数据就是用来描述环境和数据的数据,通俗地说就是配置参数,参数可以从文件中获得,也可以从数据库中获得。
Spring容器就是一个典型的元数据控制模块行为的例子,其中达到极致的就是控制反转(Inversion of Control)

3.制定项目章程

在一个团队中,建立项目章程是非常重要的,因为章程中指定了所有人员都必须遵守的约定,对项目来说,约定优于配置。

4.封装变化

对变化的封装包含两层含义:
第一,将相同的变化封装到一个接口或者抽象类中;
第二,将不同的变化封装到不同的接口或抽象类中,不应该有两个不同的变化出现在同一个接口或抽象类中。

这里给出一个简单的Java示例来说明如何实现开闭原则:
假设有一个图形类(Shape),它具有一个计算面积的方法(getArea)。我们希望能够计算不同类型的图形的面积。
首先,定义一个抽象类 Shape,包含一个抽象方法 getArea():

    public abstract double getArea();
}

然后,创建具体的图形类 Circle 和 Rectangle,并分别继承 Shape 类:

class Circle extends Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }
    
    @Override
    public double getArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle extends Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    
    @Override
    public double getArea() {
        return width * height;
    }
}

现在,我们可以使用这些具体的图形类来计算不同类型图形的面积,而无需修改 Shape 类的代码。

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(5);
        System.out.println("Circle area: " + circle.getArea());
        
        Shape rectangle = new Rectangle(4, 6);
        System.out.println("Rectangle area: " + rectangle.getArea());
    }
}

通过以上的设计,如果需要新增一种图形类型,只需要创建一个新的类并继承自 Shape 类即可,而不需要修改 Shape 类或其他已有代码。
这样的设计实现了开闭原则,对于扩展是开放的(通过创建新类来实现),对于修改是关闭的(不需要修改已有的代码)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值