2

嗨,我的任务是重构一部分代码,以使其符合开放/封闭原则。我设法在两种方法中应用了策略模式,但在一种方法中,我不知道应该如何进行。

public ProductPriceCalculator(Product product)
{
    this.product = product;
    buyerStrategy = new BuyerStrategy();
    discountStrategy = new DiscountStrategy();
}

public Price CalculatePrice()
{
    price = new Price();

    decimal productPrice = product.BasePrice + 
                           (product.BasePrice * product.Addition);
    decimal TVA = CalculateTVA();
    price.ProductPrice = productPrice*TVA;
    decimal discount = CalculateDiscount(price.ProductPrice);
    price.Discount = price.ProductPrice * discount;
    price.ProductPriceWithDiscount = price.ProductPrice - price.Discount;
    price.TransportPrice = product.Transport.GetTransportPrice();
    price.TotalPrice = price.ProductPriceWithDiscount + price.TransportPrice;

    return price;
} 

在这种情况下,此方法通过使用类中的方法初始化对象。就目前而言,此方法不会关闭以进行修改,因为如果在某些时候我必须向 Price 添加另一个属性,我将不得不回到这里来初始化它。

如何正确构建此代码?

4

2 回答 2

5

一种可能的解决方案如下:

 public class ProductPriceCalculator
 {
    private readonly Product _product;
    private readonly BuyerStrategy _buyerStrategy;
    private readonly DiscountStrategy _discountStrategy;
    private readonly Price _price;

    public ProductPriceCalculator(Product product,BuyerStrategy buyerStrategy,DiscountStrategy discountStrategy,Price price)
    {
        _product = product;
        _buyerStrategy = buyerStrategy;
        _discountStrategy = discountStrategy;
        _price = price;
    }

    public Price CalculatePrice()
    {
        decimal productPrice = _product.BasePrice + (_product.BasePrice * _product.Addition);
        decimal TVA = CalculateTVA();
        decimal discount = CalculateDiscount(productPrice * TVA);
        decimal transportPrice = _product.Transport.GetTransportPrice();

        return _price.CalculatePrice(productPrice*TVA,discount,transportPrice);
    }

    ...

 }

public class Price
{
    ...

    public virtual Price CalculatePrice(decimal productPrice, decimal discount, decimal transportPrice)
    {
        Price price = new Price();

        price.ProductPrice = productPrice;
        price.Discount = ProductPrice * discount;
        price.ProductPriceWithDiscount = ProductPrice - Discount;
        price.TransportPrice = transportPrice;
        price.TotalPrice = ProductPriceWithDiscount + TransportPrice;

        return price;
    }

    ...

}

最好将依赖项(例如buyerStrategy, discountStrategy, price)放在构造函数中,而不是通过 IoC 容器或其他东西填充它们,而不是在构造函数本身中创建它们。引入_price字段后,您可以将填充价格的属性委托给Price类本身。方法Price.CalculatePrice可以称为Price类的 Fabric 方法。

于 2013-04-19T14:55:28.530 回答
1

如果不了解更多关于周围代码的信息,很难说 - 但我想也许装饰器模式可以解决这个问题?!所以在你的例子中,也许是这样的:

public abstract class BaseProduct
{
    public decimal BasePrice { get; set; }
    public decimal Addition { get; set; }
    public Transport Transport { get; set; }

    public abstract void CalculatePrice(decimal discount);
}

public class Product : BaseProduct
{
    public BasePrice Price { get; set; }

    public Product(BasePrice price)
    {
        this.Price = price;
    }

    public override void CalculatePrice(decimal discount)
    {
        this.Price.CalculatePrice(this.BasePrice, this.Addition, discount);
    }
}

public abstract class BasePrice
{
    public abstract void CalculatePrice(decimal basePrice, decimal additional, decimal discount);
}

public class Price : BasePrice
{
    public decimal ProductPrice { get; set; }
    public decimal Discount { get; set; }
    public decimal ProductPriceWithDiscount { get; set; }
    public decimal TransportPrice { get; set; }
    public decimal TotalPrice { get; set; }

    public override void CalculatePrice(decimal basePrice, decimal additional, decimal discount)
    {
        this.ProductPrice = basePrice + (basePrice * additional);
        this.Discount = this.ProductPrice * discount;
        this.ProductPriceWithDiscount = this.ProductPrice - this.Discount;
        this.TotalPrice = this.ProductPriceWithDiscount + this.TransportPrice;
    }
}

使用此方法,您可以在添加新属性时创建 BasePrice 的新具体实现,并且仍然支持封闭原则,因为您不需要更改原始类中的计算逻辑,只需在更改时添加新的具体实现即可。澄清一下——产品是组件,价格是装饰器。

希望我做对了——欢迎任何反馈!同样,希望它有所帮助!:)

于 2013-04-19T12:38:17.677 回答