设计模式-设计原则-开闭原则

开闭原则

概念

  1. 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则
  2. 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节
  3. 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
  4. 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则

特点

  • 扩展开放(对提供方)
  • 修改关闭(对使用方)
  • 抽象构建框架
  • 实现扩展细节

场景介绍

​ 现在需要做一个画图形的功能 通过GraphicEditor类实现不同类型绘图

违反–开闭原则


在这里插入图片描述

public class OCP {
    public static void main(String[] args) {
        GraphicEditor graphicEditor = new GraphicEditor();
        graphicEditor.drawShape(new Rectangle());
        graphicEditor.drawShape(new Circle());
    }
}

class GraphicEditor{
    public void drawShape(Shape shape){
        if(shape.m_type == 1){
            drawRectangle(shape);
        }
        else if(shape.m_type == 2){
            drawCircle(shape);
        }
    }
    private void drawRectangle(Shape s){
        System.out.println(s.m_type + "画出:一个矩形");
    }

    private void drawCircle(Shape s){
        System.out.println(s.m_type + "画出:一个圆形");
    }
}

class Shape{
    int m_type;
}
class Rectangle extends Shape{
    Rectangle(){
        super.m_type = 1;
    }
}
class Circle extends Shape{
    Circle(){
        super.m_type = 2;
    }
}
//---------

运行结果

在这里插入图片描述

​ 可以看到GraphicEditor基本实现了只通过一个drawShape()就能实现不同形状的绘制
​ 但是,如果此时我们提出新增一个画 三角形 的需求,会发现需要直接修改drawShape() 同时还需要再重新创建三角形子类 GraphicEditor还需要增加对应三角形方法

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 shape){
        if(shape.m_type == 1){
            drawRectangle(shape);
        }
        else if(shape.m_type == 2){
            drawCircle(shape);
        } else if (shape.m_type == 3) {
            drawTriangle(shape);
        }
    }
    private void drawRectangle(Shape s){
        System.out.println(s.m_type + "画出:一个矩形");
    }
    private void drawCircle(Shape s){
        System.out.println(s.m_type + "画出:一个圆形");
    }

    //新增
    private void drawTriangle(Shape s){
        System.out.println(s.m_type + "画出:一个三角形");
    }
}

class Shape{
    int m_type;
}
class Rectangle extends Shape{
    Rectangle(){
        super.m_type = 1;
    }
}
class Circle extends Shape{
    Circle(){
        super.m_type = 2;
    }
}

//新增
class Triangle extends Shape{
    Triangle(){
        super.m_type = 3;
    }
}

在这里插入图片描述


遵循–开闭原则
在这里插入图片描述

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());
    }
}
//此时使用者GraphicEditor不需要根据 业务新增子类而变化代码  实现OCP原则
class GraphicEditor{
    public void drawShape(Shape shape) {
        shape.draw();
    }
}

//抽象基类  额外增加一个draw()方法供子类实现 及其他使用者调用
abstract class Shape{
    int m_type;
    void draw(){};
}
class Rectangle extends Shape{
    Rectangle(){
        super.m_type = 1;
    }

    @Override
    void draw() {
        System.out.println(this.m_type + "画出:一个矩形");
    }
}
class Circle extends Shape{
    Circle(){
        super.m_type = 2;
    }

    @Override
    void draw() {
        System.out.println(this.m_type + "画出:一个圆形");
    }
}

//新增
class Triangle extends Shape{
    Triangle(){
        super.m_type = 3;
    }

    @Override
    void draw() {
        System.out.println(this.m_type + "画出:一个三角形");
    }
}

运行结果

在这里插入图片描述

​ 基类Shape新增一个抽象方法 draw()该方法可以提供给使用者GraphicEditor 且Shape子类实现时GraphicEditor不需要做修改


注意实现及细节

这里的做法和依赖倒置的解决方法很相似 同样都是抽取出公用的方法作为接口

  1. 软件(类、模块和函数)应该对扩展开放,对修改关闭
  2. 抽象构建框架,用实现扩展细节
  3. 软件需要变化时,尽量通过 拓展软件实体的行为来实现变化,而不是通过修改已有代码来实现变化
  4. 编程遵循其他原则,及使用设计模式就是为了实现开闭原则
  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值