1. 开闭原则

一、开闭原则

1. 概念

当我们需要添加一个新的功能时,应该在已有代码基础上扩展代码(新增模块、类、方法等),而非修改已有代码(修改模块、类、方法等)。

开闭原则有一个很重要的特性就是:对扩展开放,对修改关闭

在程序需要拓展的时候,不能去修改原有代码,实现一个热插拔的效果(即插即用),这样写出来的程序才能具有良好的扩展性,易于维护性。

2. 如何才能实现开闭原则呢?

想要达到这样的效果,我们需要使用接口和抽象类。

因为抽象/接口灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。

举个例子:

class Order {
    private double totalAmount;
    public Order(double totalAmount) {
        this.totalAmount = totalAmount;
    }
    // 计算折扣后的金额
    public double getDiscountedAmount(String discountType) {
        double discountedAmount = totalAmount;
        if (discountType.equals("FESTIVAL")) {
            discountedAmount = totalAmount * 0.9; // 节日折扣,9折
        } else if (discountType.equals("SEASONAL")) {
            discountedAmount = totalAmount * 0.8; // 季节折扣,8折
        }
        return discountedAmount;
    }
}

上述代码要完成的是电商的折扣卷计算的方法,Order 类包含一个计算折扣金额的方法,它根据不同的折扣类型应用折扣。当我们需要添加新的折扣类型时,就不得不需要修getDiscountedAmount 方法的代码,这显然是不合理的,这就违反了开闭原则。

正确遵守开闭原则的代码:

// 抽象折扣策略接口
interface DiscountStrategy {
    double getDiscountedAmount(double totalAmount);
}
// 节日折扣策略
class FestivalDiscountStrategy implements DiscountStrategy {
    @Override
    public double getDiscountedAmount(double totalAmount) {
    return totalAmount * 0.9; // 9折
    }
}
// 季节折扣策略
class SeasonalDiscountStrategy implements DiscountStrategy {
    @Override
    public double getDiscountedAmount(double totalAmount) {
    return totalAmount * 0.8; // 8折
    }
}
class Order {
    private double totalAmount;
    private DiscountStrategy discountStrategy;
    public Order(double totalAmount, DiscountStrategy discountStrategy) {
        this.totalAmount = totalAmount;
        this.discountStrategy = discountStrategy;
    }
    public void setDiscountStrategy(DiscountStrategy discountStrategy) {
        this.discountStrategy = discountStrategy;
    }
    // 计算折扣后的金额
    public double getDiscountedAmount() {
        return discountStrategy.getDiscountedAmount(totalAmount);
    }
}

3. 练习

我们应该都玩过王者荣耀吧,王者荣耀里面挣钱的就是皮肤,天美工作室给某个英雄出了一款新皮肤,如果我们是游戏开发工程师应该如何写?

/**
 * 抽象皮肤类,用来定义所有皮肤的规则
 *
 * @author wty
 */
public abstract class AbstractSkin {
    /**
     * 用来显示皮肤
     */
    public abstract void display();
}

/**
 * 默认皮肤
 *
 * @author wty
 */
public class DefaultSkin extends AbstractSkin {
    @Override
    public void display() {
        System.out.println("默认皮肤");
    }
}
/**
 * 新上架的皮肤
 *
 * @author wty
 */
public class NewSkin extends AbstractSkin {
    @Override
    public void display() {
        System.out.println("妲己的新皮肤");
    }
}

/**
 * 王者荣耀游戏
 */
public class HonorOfKingsOutput {
    private AbstractSkin skin;

    public void setSkin(AbstractSkin skin) {
        this.skin = skin;
    }

    public void display() {
        skin.display();
    }
}

/**
 * 测试类
 */
public class Test {
    public static void main(String[] args) {
        HonorOfKingsOutput honorOfKingsOutput = new HonorOfKingsOutput();
        honorOfKingsOutput.setSkin(new NewSkin());
        honorOfKingsOutput.display();
    }
}

假如我们妲己最近玩的人很多,又想出一款新的皮肤,那么我们只需要创建一个新的类去实现抽象皮肤类去实现方法即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值