【问题标题】:Decorator pattern example装饰器模式示例
【发布时间】:2013-12-06 03:02:15
【问题描述】:

我正在浏览装饰器设计模式,发现每个示例都使用一个抽象装饰器类,并且还实现了装饰器所针对的类的接口创建的。我的问题是,

  1. 是否需要有一个抽象的装饰器类,然后定义具体的装饰器?

  2. 我创建了一个示例,我认为它可以类似于上述抽象类方法所实现的功能。

     public interface ICarModel
     {
       Int32 Price { get; }
       Int32 Tax { get; }
     }
    
     public class BaseModel : ICarModel
     {
       public Int32 Price
       {
         get { return 50000; }
       }
    
       public Int32 Tax
       {
         get { return 5000; }
       }
    
       public String GetBaseCarDetails()
       {
         return "Base car model Price is : " + this.Price
           + " and Tax is : " + this.Tax;
       }
     }
    
     public class LuxuryModel
     {
       ICarModel _iCarModel;
    
       public LuxuryModel(ICarModel iCarModel)
       {
         _iCarModel = iCarModel;
       }
    
       public Int32 Price
       {
         get { return _iCarModel.Price + 10000; }
       }
    
       public Int32 Tax
       {
         get { return _iCarModel.Tax + 3000; }
       }
    
       public String GetLuxuryCarDetails()
       {
         return "Luxury car model Price is : " + this.Price
           + " and Tax is : " + this.Tax;
       }
     }
    

    我们可以说这是装饰器模式的一个例子吗?

【问题讨论】:

  • @yannishristofakis 据我所知,get{ } 属性是 C# 独有的。不过不确定。
  • 您的第一个问题可能与 this 重复
  • @Kalyan,这似乎是同一个问题,但不幸的是,我无法解释他在这里试图解释的确切含义。你能解释一下这个解释吗?
  • @TechJay 我试图在下面的回答中解释这一点。

标签: c# design-patterns


【解决方案1】:

更新

我们真的需要把装饰器做成抽象类吗?

我想您可以避免使用abstract,但是您必须为所有类编写相同的代码。 abstract 的目的是避免冗余代码并确保您的类符合相同的逻辑。此外,它更易于维护和扩展。

Decorator Pattern

【讨论】:

  • 谢谢亚尼斯。这可能是装饰器模式的实现。其实我的意思是我们真的需要把装饰器做成抽象类吗?
  • @TechJay 我做了一个解释,我希望它有意义。
  • 根据您的评论,我认为如果我们使用接口和 DI,就不会有任何冗余代码。我们只需要使用接口容器传递适当的依赖项。
  • @TechJay 正如我告诉你的那样,这不是必需的,但它被认为是最佳实践,因为它是一种设计模式。如果你有一个模型,那没什么大不了的。但是如果你有很多很多方法,实现一个 abstract 类就很方便了。 DI 代表什么? 依赖注入?
【解决方案2】:

Model1 是一个装饰器,它将其“getPrice”逻辑的一部分委托给被装饰者“CarModel”

class Model1 implements IModel
{
    IModel m_model;

    Model1(CarModel model){
        m_model = model;
    }

    public int getPrice(){
        return m_model.getPrice() + getModelSpecificPrice();
    }

    protected int getModelSpecificPrice(){
        return 10;
    }
}

但是如果有Model2、Model3等,'getPrice'方法的逻辑是一样的呢?

在这种情况下,创建一个抽象装饰器是有意义的

class AbstractModel implements IModel{
        IModel m_model;

        AbstractModel(CarModel model){
            m_model = model;
        }

        public int getPrice(){
            return m_model.getPrice() + getModelSpecificPrice();
        }

        abstract protected int getModelSpecificPrice();
}


class Model1 extends AbstractModel
{

    Model1(CarModel model){
        super(model);
    }
    protected int getModelSpecificPrice(){
        return 10;
    }
}

【讨论】:

    【解决方案3】:

    装饰器模式的目的只是扩展现有类型的行为,使该类型的消费者不需要知道它如何更改的实现细节。

    任何类型都不需要是抽象的。您可以使用接口或具体类上的虚拟方法来执行此操作。

    【讨论】:

    • 你的意思是我们可以使用依赖注入和接口来注入适当的基础功能并扩展它?
    • +1 consumers of that type don't need to know the implementation details
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-25
    • 1970-01-01
    • 1970-01-01
    • 2014-07-07
    相关资源
    最近更新 更多