设计模式中什么是开闭原则?

简介

开闭原则(Open-Closed Principle,OCP)是面向对象设计中的一个重要原则,由勃兰特·梅耶(Bertrand Meyer)在他的著作《面向对象软件构造》(Object-Oriented Software Construction)中首次提出。这个原则强调软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。换句话说,当需要改变系统的行为或者添加新功能时,应该尽量避免修改已有的代码,而是通过扩展已有的代码来实现变化。

具体来说,开闭原则包含以下两个核心概念:

  1. 开放性(Open for Extension):软件实体应该允许在不修改已有代码的情况下进行扩展。这意味着应该设计软件结构以便可以新增功能,而不需要修改现有的代码。

  2. 封闭性(Closed for Modification):软件实体在扩展时不应该修改其已有的代码。这意味着对已有的代码进行修改时应该小心谨慎,避免因此引入新的错误或导致已有功能的失效。

开闭原则的实现通常通过一些设计模式来完成,例如策略模式、观察者模式、装饰者模式等。这些模式使得系统更易于扩展,同时保持了系统的稳定性和可维护性。

违法开闭原则示例

public interface Noodle {

    /**
     *  制作接口类
     * @author yiridancan
     **/
    void cook();

}
/**
 * 牛肉面实现类
 * @author yiridancan
 **/
public class BeefNoodle implements Noodle{
    @Override
    public void cook() {
        System.out.println("牛肉面正在准备中...");
    }
}



/**
 * 鸡肉面实现类
 * @author yiridancan
 **/
public class ChickenNoodle implements Noodle{
    @Override
    public void cook() {
        System.out.println("鸡肉面正在准备中...");
    }
}


/**
 * 素面实现类
 * @author yiridancan
 **/
public class VegetarianNoodle implements Noodle{
    @Override
    public void cook() {
        System.out.println("素面正在准备中...");
    }
}
/**
 * 简单工厂类
 * @author yiridancan
 **/
public class NoodleFactory {

    public static Noodle getNoodle(String type){
        switch (type){
            case "beef":
                return new BeefNoodle();
            case "chicken":
                return new ChickenNoodle();
            case "vegetarian":
                return new VegetarianNoodle();
            default:
                return null;
        }
    }

}
    @Test
    public void factoryTest(){
        //鸡肉面
        Noodle chicken = NoodleFactory.getNoodle("chicken");
        chicken.cook();

        //牛肉面
        Noodle beef = NoodleFactory.getNoodle("beef");
        beef.cook();

        //素面
        Noodle vegetarian = NoodleFactory.getNoodle("vegetarian");
        vegetarian.cook();
    }

当我们需要增加面的类型时,比如排骨面。这个时候我们就需要先定义一个RibsNoodle类,其中实现排骨面的代码。除此之外我们还要修改NoodleFactory类的代码,增加一个case。这显然是违背开闭原则的

符合开闭原则示例

public interface NoodleFactory {

    /**
     *  面条工厂接口
     * @author yiridancan
     **/
    Noodle createNoodle();
}
/**
 *  具体的工厂类:牛肉面工厂
 * @author yiridancan
 **/
public class BeefNoodleFactory implements NoodleFactory{
    @Override
    public Noodle createNoodle() {
        return new BeefNoodle();
    }
}


/**
 *  具体的工厂类:鸡肉面工厂
 * @author yiridancan
 **/
public class ChickenNoodleFactory implements NoodleFactory{
    @Override
    public Noodle createNoodle() {
        return new ChickenNoodle();
    }
}


/**
 *  具体的工厂类:素面工厂
 * @author yiridancan
 **/
public class VegetarianNoodleFactory implements NoodleFactory{
    @Override
    public Noodle createNoodle() {
        return new VegetarianNoodle();
    }
}
    @Test
    public void factoryTest(){
        // 创建牛肉面工厂,并制作牛肉面
        NoodleFactory beefNoodleFactory = new BeefNoodleFactory();
        Noodle beefNoodle = beefNoodleFactory.createNoodle();
        beefNoodle.cook();

        // 创建鸡肉面工厂,并制作鸡肉面
        NoodleFactory chickenNoodleFactory = new ChickenNoodleFactory();
        Noodle chickenNoodle = chickenNoodleFactory.createNoodle();
        chickenNoodle.cook();

        // 创建素面工厂,并制作素面
        NoodleFactory vegetarianNoodleFactory = new VegetarianNoodleFactory();
        Noodle vegetarianNoodle = vegetarianNoodleFactory.createNoodle();
        vegetarianNoodle.cook();
    }

在这个示例中,我们结合了策略模式和工厂模式。首先,我们定义了面条接口 Noodle 和具体的面条类:BeefNoodleChickenNoodle VegetarianNoodle

然后,我们定义了面条工厂接口 NoodleFactory 和具体的面条工厂类:BeefNoodleFactoryChickenNoodleFactory VegetarianNoodleFactory。每个工厂类负责创建对应类型的面条。

最后,测试代码中,我们根据需要创建不同的面条工厂,并调用工厂的 createNoodle 方法来创建不同类型的面条对象,然后调用 cook 方法来制作面条。这样一来,当需要新增一种面条类型时,只需创建对应的工厂类即可,不需要修改已有的工厂类或其他已有的代码,符合开闭原则。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值