开闭原则(Open Closed Principle)

1. 概念

  • 对扩展开放(对提供方),对修改关闭(对使用方)

2. 分析

  • 不“开闭”的坏处
    • 牵一发而动全身
  • 好处
    • 测试简单
    • 可复用性变强
    • 稳定性变高
  • 实现方式
    • 接口、抽象类

3. 代码示例

示例1

  • 优点是比较好理解,简单易操作
  • 缺点是违反了设计模式的ocp原则,即对扩展开放(提供方),对修改关闭(修改方)。即当我们给类增加新功能的时候,尽量不修改代码,或者尽可能少修改代码
  • 比如我们这时要新增加一个图形种类,我们需要做如下修多改,修改的地方较多
package com.bz.design.principle.ocp;

public class Ocp {
    public static void main(String[] args) {
        // 使用看看存在的问题
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawRectangle(new Rectangle());
        graphicEditor.drawCircle(new Circle());
    }
}
// 使用方
class GraphicEditor {
    public void drawShape(Shape s) {
        if (s.m_type == 1) {
            drawRectangle(s);
        } else if (s.m_type == 2) {
            drawCircle(s);
        }
        // 新增图形这里需要修改
    }
    public void drawRectangle(Shape r) {
        System.out.println("绘制矩形");
    }
    public void drawCircle(Shape r) {
        System.out.println("绘制圆形");
    }
    // 新增图形这里需要修改
}
// 基类
class Shape {
    int m_type;
}
class Rectangle extends Shape {
    Rectangle() {
        this.m_type = 1;
    }
}
class Circle extends Shape {
    Circle() {
        this.m_type = 2;
    }
}

示例2

  • 改进思路
    • 把创建Shape类做成抽象类,并提供一个抽象的draw方法,让子类去实现即可,这样我们有新的图形种类时,只需要让新的图形类继承Shape,并实现draw方法即可,使用方的代码就不需要修改 --> 满足了开闭原则
package com.bz.design.principle.ocp.improve;

/**
 * @Description: 开闭原则
 * 方式2分析: 定义抽象类
 *
 */
public class Ocp {
    public static void main(String[] args) {
        // 调用
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
        graphicEditor.drawShape(new Triangle());
    }
}
// 使用方
class GraphicEditor {
    public void drawShape(Shape s) {
        s.draw();
    }
}
// Shape类,基类
abstract class Shape {
    int m_type;
    // 抽象方法
    public abstract void draw();
}
class Rectangle extends Shape {
    Rectangle() {
        this.m_type = 1;
    }
    @Override
    public void draw() {
        System.out.println("绘制矩形");
    }
}
class Circle extends Shape {
    Circle() {
        this.m_type = 2;
    }
    @Override
    public void draw() {
        System.out.println("绘制圆形");
    }
}
class Triangle extends Shape {
    Triangle() {
        this.m_type = 3;
    }
    @Override
    public void draw() {
        System.out.println("绘制三角形");
    }
}

4. 应用注意事项

  • 开放和关闭
    • 拓展开放:应对变化
    • 修改关闭:保持稳定性
  • 注意事项
    • 用抽象构建框架,用实现扩展细节
    • 参数类型、引用对象尽量使用接口或者抽象类
    • 抽象层尽量保持稳定:接口和抽象类只负责定义方法,,不负责具体实现
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容