gpt4 book ai didi

c# - 创建装饰器。设计模式

转载 作者:行者123 更新时间:2023-12-01 19:29:32 25 4
gpt4 key购买 nike

假设定义了两个简单的装饰器:

// decorated object
class Product : IComponent {
// properties..
// IComponent implementation
public Decimal GetCost() {
return this.SelectedQuantity * this.PricePerPiece;
}
}

// decorators
class FixedDiscountDecorator : IComponent {
IComponent component;
// IComponent implemantation
public Decimal GetCost() {
// ...
}
public FixedDiscountDecorator(IComponent product, Decimal discountPercentage) {
// ...
}
}

class BuyXGetYFreeDiscountDecorator : IComponent {
IComponent component;
// IComponent implemantation
public Decimal GetCost() {
// ...
}
// X - things to buy
// Y - things you get free
public BuyXGetYFreeDiscountDecorator(IComponent product, Int32 X, Int32 Y) {
// ...
}
}

这些装饰器具有不同的构造函数签名(参数列表)。我正在寻找一种适用于构造装饰器的模式,就像工厂模式一样。我的意思是我放置一个字符串并获取一个装饰器实例。

因此,我想简单地将装饰器链应用于给定的产品:

var product = new SimpleProduct {
Id = Guid.NewGuid(),
PricePerPiece = 10M,
SelectedQuantity = 10,
Title = "simple product"
};

var itemsToApplyTheDiscount = 5;
var itemsYouGetFree = 2;
var discountPercentage = 0.3M;

var discountA = new BuyXGetYFreeDecorator(product, itemsToApplyTheDiscount, itemsYouGetFree);
var discountB = new FixedDiscountDecorator(discountA, discountPercentage);

最佳答案

这可以使用 IOC 容器或类似的东西来解决。我脑海中浮现的一些容器是 UnityWindsorSimpleInjector。我将把 IOC 容器留给其他答案,因为我没有这方面的经验。

但是,我真的很想知道为什么要注入(inject)原生值。

了解该类的使用方式后,将诸如折扣百分比或 x 购买 y 免费元素之类的注入(inject)值注入(inject)到构造函数中感觉很奇怪。

如果用户将 10(百分比)而不是 0.1(小数)作为折扣参数怎么办?它造成歧义。此外,如果您在构造函数中添加检查,则会给该类带来另一项责任,从而违反了 SRP。

我建议添加 DTO,例如 DiscountPercentValueBuyXGetYFreeValue。此外,我更喜欢将折扣值设置为上下文,或者为其注入(inject)一个存储库。否则,有一天您将需要工厂来处理与折扣相关的if-else业务规则。

编辑1:

通常我只将构造函数验证保留为 null 检查。除此以外的其他验证都可以被视为违规。

至于存储库的东西,我想象一些像这样的接口(interface):

public interface IDiscountPercentageProvider{
DiscountValue Get();
}

public interface IBuyXGetYFreeValueProvider{
BuyXGetYFreeValue Get();
}

然后在您的服务类中,您可以使用如下内容:

class FixedDiscountDecorator : IComponent {
IComponent component;
// IComponent implemantation
IDiscountPercentageProvider discountPercentageProvider;
public Decimal GetCost() {
DiscountValue discount = discountPercentageProvider.Get();
// ...
}
public FixedDiscountDecorator(IComponent product
, IDiscountPercentageProvider discountPercentageProvider) {
// ... just null checks here
}
}

一开始这可能会很复杂。然而,它提供了更好的 API 设计(现在使用装饰器时没有歧义)。使用它,您可以创建一个 DiscountValue 作为 protects its invariants 的类。 ,使其在其他类中使用更加安全。

关于c# - 创建装饰器。设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18589866/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com