朝着理想坚实迈进_坚实原则:开放/封闭原则

朝着理想坚实迈进

先前我们讨论了单一责任原则。 关于实体原则首字母缩写, 打开/关闭原则是该行中的第二个原则。

“软件实体(类,模块,功能等)应打开以进行扩展,但应关闭以进行修改”

通过采用该原理,目标是在不修改其源代码的情况下扩展模块的行为。

想象一下对我们的一种产品应用折扣的情况。 折扣服务将应用指定的折扣并返还​​折扣价。

目前,我们的系统只有一种折扣适用于所有成年人。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Discount {

    public BigDecimal apply(BigDecimal price) {

        BigDecimal percent = new BigDecimal("0.10");
        BigDecimal discount = price.multiply(percent);
        return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
    }
}

折扣服务应将此折扣应用于给出的价格。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;

public class DiscountService {

    public BigDecimal applyDiscounts(BigDecimal price,Discount discount) {

        BigDecimal discountPrice = price.add(BigDecimal.ZERO);
        discountPrice = discount.apply(discountPrice);
        return discountPrice;
    }
}

但是,我们公司希望为老年人提供折扣,因此我们有老年人折扣。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class SeniorDiscount {

    public BigDecimal apply(BigDecimal price) {

        BigDecimal percent = new BigDecimal("0.20");
        BigDecimal discount = price.multiply(percent);
        return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
    }
}

折扣服务使事情变得有些复杂,因为该服务必须同时应用成人折扣和老年人折扣。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;

public class DiscountService {

    public BigDecimal applyDiscounts(BigDecimal price,Discount discount) {

        BigDecimal discountPrice = price.add(BigDecimal.ZERO);
        discountPrice = discount.apply(discountPrice);
        return discountPrice;
    }

    public BigDecimal applySeniorDiscount(BigDecimal price,SeniorDiscount discount) {

        BigDecimal discountPrice = price.add(BigDecimal.ZERO);
        discountPrice = discount.apply(discountPrice);
        return discountPrice;
    }

}

通过这样做,我们修改了折扣服务源代码以扩展其行为。 同样,对于销售部门可能提出的每一种不同的折扣,折扣服务也会获得额外的方法。

为了遵循开放/封闭原则,我们将创建一个折扣界面。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;

public interface Discount {

    BigDecimal apply(BigDecimal price);
}

默认折扣将重命名为AdultDiscount并实现折扣界面。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class AdultDiscount implements Discount {

    @Override
    public BigDecimal apply(BigDecimal price) {

        BigDecimal percent = new BigDecimal("0.10");
        BigDecimal discount = price.multiply(percent);
        return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
    }
}

SeniorDiscount也将实现Discount接口。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class SeniorDiscount implements Discount {

    @Override
    public BigDecimal apply(BigDecimal price) {

        BigDecimal percent = new BigDecimal("0.20");
        BigDecimal discount = price.multiply(percent);
        return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
    }
}

最后但并非最不重要的一点是,我们将对DiscountService进行重构,以便基于Discount接口应用折扣。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;

public class DiscountService {

    public BigDecimal applyDiscounts(BigDecimal price,Discount[] discounts) {

        BigDecimal discountPrice = price.add(BigDecimal.ZERO);

        for(Discount discount:discounts) {

            discountPrice = discount.apply(discountPrice);
        }

        return discountPrice;
    }
}

通过这种方式,折扣服务将能够应用不同的折扣而无需更改其源代码。

可以对折扣应用相同的原理。
假设我们希望有一个基本折扣可以在应用折扣时额外应用。

package com.gkatzioura.solid.ocp;

import java.math.BigDecimal;
import java.math.RoundingMode;

public abstract class BasicDiscount implements Discount {

    @Override
    public BigDecimal apply(BigDecimal price) {

        BigDecimal percent = new BigDecimal("0.01");
        BigDecimal discount = price.multiply(percent);
        return price.subtract(discount.setScale(2, RoundingMode.HALF_UP));
    }
}

通过扩展BasicDiscount类,我们可以在BasicDiscount的行为上获得更多折扣,并且还可以在不修改BasicDiscount源代码的情况下扩展此行为。

您可以在github上找到源代码。 下一个原理是liskov替换原理。

另外,我还编写了备忘单,其中包含有关扎实原则的摘要。
链接中注册以接收它。

翻译自: https://www.javacodegeeks.com/2018/02/solid-principles-open-closed-principle.html

朝着理想坚实迈进

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值