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

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

一.定义

  • 开闭原则(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());
    }
}

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

相关推荐
一个 00 后的码农2 小时前
26考研物理复试面试常见问答问题汇总(2)电磁波高频面试问题,物理专业保研推免夏令营面试问题汇总
考研·面试·职场和发展
Gavynlee3 小时前
plantuml用法总结
设计模式
DKPT4 小时前
Java享元模式实现方式与应用场景分析
java·笔记·学习·设计模式·享元模式
缘来是庄4 小时前
设计模式之迭代器模式
java·设计模式·迭代器模式
No Silver Bullet5 小时前
软件工程功能点估算基础
软件工程·功能点估算
No Silver Bullet5 小时前
软件工程功能点估算法常用术语介绍
java·开发语言·软件工程
摘星编程7 小时前
深入解析迭代器模式:优雅地遍历聚合对象元素
设计模式·迭代器模式·软件开发·编程技巧·面向对象设计
DKPT11 小时前
Java桥接模式实现方式与测试方法
java·笔记·学习·设计模式·桥接模式
新中地GIS开发老师15 小时前
新发布:26考研院校和专业大纲
学习·考研·arcgis·大学生·遥感·gis开发·地理信息科学
缘来是庄18 小时前
设计模式之中介者模式
java·设计模式·中介者模式