【问题标题】:How to remove decorators out of order in C#如何在 C# 中乱序删除装饰器
【发布时间】:2011-10-07 02:07:01
【问题描述】:

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

假设我做了以下事情

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

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

我需要让用户无序地移除装饰器,例如,在不移除皮革座椅和安全气囊的情况下移除电动车窗

【问题讨论】:

标签: c# design-patterns decorator


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我可能会用Chain of responsibility 解决这个问题。我会创建一个处理程序接口

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

    然后我会创建处理程序实现,即 ElectricWindowHandler、LeatherHandler 等,例如 CanHandle() => if option == UserOption.electric then Handle() => car.Accessories.Add(new ElectricWindow);

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

    【讨论】:

      【解决方案3】:

      可能有一个集中的对象,它告诉您哪个模型已弃用哪些功能,因此您不必完全更改每个装饰器模式。只是对其中的一个小修改,我的意思是在 ElectricWindows 返回 Car 对象之前,它会检查它是否有资格拥有此功能。 希望我说得通!

      【讨论】:

        【解决方案4】:

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

        在您的问题中,您规定可以无序删除 Decorators,这基本上使 kibosh 推荐使用 Undo/RedoDecorate/UnDecorate 方法。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-08-27
          • 2019-08-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-27
          • 2018-11-16
          • 2011-09-12
          相关资源
          最近更新 更多