软件设计模式原则(二)开闭原则

继续讲解第二个重要的设计模式原则------开闭原则~

一.定义

  • 开闭原则(Open Closed Principle)是编程中最基础、最重要的设计原则。
  • 一个软件实体如类,模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)。用抽象构建框架,用实现扩展细节。
  • 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
  • 编程中遵循其它原则,以及使用设计模式的目的就是遵循开闭原则。
  • 所谓对扩展开放:指的是我们系统中的模块、类、方法对它们的提供者(开发者)应该是开放的,提供者可以对系统进行扩展(新增)新的功能。
  • 所谓对修改关闭:指的是系统中的模块、类、方法对它们的使用者(调用者)应该是关闭的,使用者使用这些功能时,不会因为提供方新增了功能而导致使用者也进行相应修改。

二.描述

开闭原则是面向对象程序设计的终极目标,它使软件实体拥有一定的适应性和灵活性的同时具备稳定性和延续性~

  • 对软件测试的影响
  • 可以提高代码的可复用性
  • 可以提高软件的可维护性

三.案例

举个简单的例子,假设你的女票(使用方)有一天收到了你送给她的礼物------这礼物有可能是情书,也有可能是手工书~则实现的代码如下:

java 复制代码
//礼物类基类
class gift{
    String type;
}
class Letter extends gift{
    Letter(){
        super.type="Letter";
    }
}

class Handwork extends gift{
    Handwork(){
        super.type="Handwork";
    }
}

//使用方类,也就是接收方类
class girlfriend{
    public void drawShape(gift g) {
        if (g.type == "Letter")
            getLetter(g);
        else if (g.type == "Handwork")
            getHandwork(g);
    }

    public void getLetter(gift r) {
        System.out.println("收到的礼物是情书!");
    }
    
    public void getHandwork(gift r) {
        System.out.println("收到的礼物是手工书!");
    }
}

public class Main {
    public static void main(String[] args) {
        girlfriend hyh = new girlfriend();
        hyh.drawShape(new Letter());
        hyh.drawShape(new Handwork());

    }
}

这时加入礼物种类添加了一种类型------奢侈品,则对代码的修改如下:

java 复制代码
//礼物类基类
class gift{
    String type;
}
class Letter extends gift{
    Letter(){
        super.type="Letter";
    }
}

class Handwork extends gift{
    Handwork(){
        super.type="Handwork";
    }
}
class luxury extends gift{
    luxury(){
        super.type="luxury";
    }
}

//使用方类,也就是接收方类
class girlfriend{
    public void getgift(gift g) {
        if (g.type == "Letter")
            getLetter(g);
        else if (g.type == "Handwork")
            getHandwork(g);
        else if (g.type == "Luxury")
            getLuxury(g);

    }

    public void getLetter(gift r) {
        System.out.println("收到的礼物是情书!");
    }

    public void getHandwork(gift r) {
        System.out.println("收到的礼物是手工书!");
    }
    public void getLuxury(gift r) {
        System.out.println("收到的礼物是奢侈品!");
    }
}

public class Main {
    public static void main(String[] args) {
        girlfriend hyh = new girlfriend();
        hyh.getgift(new Letter());
        hyh.getgift(new Handwork());
        hyh.getgift(new luxury());
    }
}

此时不难发现,不仅修改了提供方(gift类)的代码,也修改了使用方(girlfriend类)的代码,即违反了所谓的开闭原则~(对修改关闭)

也就是说,当发生变更时,提供方是允许修改的,而使用方则不允许,这就是所谓的【对扩展开放,对修改关闭】。做出如下修改,即可避免:

java 复制代码
/**
 *
 */
//gift类,基类
abstract class gift {
    //声明为一个抽象类~
    String type;
    public abstract void get();//抽象方法
}

class Letter extends gift {
    Letter() {
        super.type ="Letter";
    }
    //重点在于不同的类内部具体实现所谓的方法------即重写
    @Override
    public void get() {
        System.out.println("收到的礼物是情书~");
    }
}

class Handwork extends gift {
    Handwork() {
        super.type =" Handwork";
    }
    //重点在于不同的类内部具体实现所谓的方法------即重写
    @Override
    public void get() {
        System.out.println("收到的礼物是手工书~");
    }
}

class girlfriend {
    
    public void getgift(gift g) {
        g.get();
    }
}

public class Main {
    public static void main(String[] args) {
        girlfriend hyh = new girlfriend();
        hyh.getgift(new Letter());
        hyh.getgift(new Handwork());
        
    }
}

此时我们想要再添加奢侈品Luxury类,只需要修改提供方即可,不需要修改使用方的代码:

java 复制代码
/**
 *
 */
//gift类,基类
abstract class gift {
    //声明为一个抽象类~
    String type;
    public abstract void get();//抽象方法
}

class Letter extends gift {
    Letter() {
        super.type ="Letter";
    }
    //重点在于不同的类内部具体实现所谓的方法------即重写
    @Override
    public void get() {
        System.out.println("收到的礼物是情书~");
    }
}

class Handwork extends gift {
    Handwork() {
        super.type =" Handwork";
    }
    //重点在于不同的类内部具体实现所谓的方法------即重写
    @Override
    public void get() {
        System.out.println("收到的礼物是手工书~");
    }
}
class Luxury extends gift {
    Luxury() {
        super.type ="Luxury";
    }
    //重点在于不同的类内部具体实现所谓的方法------即重写
    @Override
    public void get() {
        System.out.println("收到的礼物是奢侈品~");
    }
}

class girlfriend {

    public void getgift(gift g) {
        g.get();
    }
}

public class Main {
    public static void main(String[] args) {
        girlfriend hyh = new girlfriend();
        hyh.getgift(new Letter());
        hyh.getgift(new Handwork());
        hyh.getgift(new Luxury());
    }
}

做个总结------牢记对扩展开放,对修改关闭~

相关推荐
静水流深_沧海一粟19 小时前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder19 小时前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室1 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦2 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
码农幻想梦5 天前
3472. 八皇后(北京大学考研机试题目)
考研·算法·深度优先
holeer5 天前
【V3.0】「酒店 × 视觉AI」项目 | 需求分析说明书(软件工程概论 - 课程作业三)
人工智能·软件工程·需求分析·原型设计·总体设计·结构化设计
阿闽ooo5 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4965 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃5 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式
雾江流5 天前
Xtra 2.54.1 | Twitch直播第三方客户端,开源纯净无广
软件工程