如何在c#中删除无序的装饰器

本文关键字:无序 删除 | 更新日期: 2023-09-27 18:10:49

我正在尝试实现一个简单的应用程序,让我选择额外的汽车。每个额外的项都是一个基类Car的装饰器。

假设我执行以下操作

Car p = new FordFusion();
p = new ElectricWindows(p);
p = new LeatherSeatings(p);
p = new Airbags(p);

那么我的目标p将是一辆有电动车窗、真皮座椅和安全气囊的福特Fusion。

我需要让用户随意移除装饰,比如,在不移除真皮座椅和安全气囊的情况下移除电动车窗

如何在c#中删除无序的装饰器

听起来装饰器模式可能不是为您的领域建模的最佳方式。你的装饰师真的需要改变汽车的行为吗?或者他们只是增加了成本/价格?

您是否尝试过将ICarFeatures集合作为Car类的成员?ICarFeature可以有一个GetCost方法或类似的东西来允许将汽车的总成本加起来。

我可能会用责任链来解决这个问题。我将创建一个处理程序接口

public interface IAccessoryHandler
{ 
  bool CanHandle( UserOption option );  // UserOption is an enum of Electric Window etc.
  Handle( Car car ); 
}

然后我会创建处理程序实现,即ElectricWindowHandler, LeatherHandler等,例如CanHandle() => if option == UserOption。电动手柄()=>汽车配件。Add(new ElectricWindow);

每次用户更改选项时,我都会清除汽车配件集合,对选定的用户选项执行foreach操作,并让汽车对象在链中运行。到链条过程结束时,您的汽车将拥有正确的配件。

可以有一个集中的对象来告诉你哪个模型的哪些特性已经被弃用了,这样你就不必完全改变每个装饰器模式。只是对它们做了一个小小的修改,我的意思是在ElectricWindows返回Car对象之前,它会检查它是否有资格拥有这个特性。希望我说的有意义!!

我的回答假设您不会放弃装饰器方法。

在你的问题中,你规定可以取消Decorators的顺序,这基本上是在推荐Undo/RedoDecorate/UnDecorate方法。

我认为您可以利用Memento模式。跟踪Car和哪个Decorators被应用的状态。通过删除一个装饰器,基本上可以遍历应用的装饰器堆栈,直到所需的状态,并将Car对象恢复到该状态(之前应用已删除的装饰器)。然后,您需要重新应用此后继续进行的装饰器。可能不是最优的解决方案,但它对您当前的设计影响最小。