【问题标题】:Decorator pattern wasting memory装饰图案浪费内存
【发布时间】:2012-01-17 23:56:48
【问题描述】:

我的这个基类具有以下接口:

abstract class Base
{
  abstract public object Val
  {
    get;
  }
}

对于任何派生类,Val 的值必须在对象创建时指定。
问题是:我如何制作派生类来做到这一点(希望在编译时)?
我尝试添加一个构造函数:

abstract class Base
{
  public Base(object value)
  {
    val = value;
  }

  private object val;

  ...
}

但正如您所见,我必须声明一个私有字段来在其中存储值(因为 Value 是只读的)。
出现问题是因为我想使用 GoF 设计模式中引入的装饰器/包装器模式为派生类添加某种效果。但是因为我已经在 Base 类中声明了该字段,所以装饰器会一直保存相同数据的副本,我最终会浪费内存。

【问题讨论】:

  • 装饰器是一个持有另一个对象的对象,因此您显然需要两个对象的内存。这正是您的解决方案所需的内存。如果这不适合您,您可能误用或误解了装饰器模式。你到底想解决什么问题?
  • 如果我在 Base 类中只定义属性(而不是字段),那么装饰器实际上不必存储 Base 成员的任何其他副本。
  • 装饰器不存储任何基本成员的副本。它只是存储对装饰对象的引用!?
  • 它也必须从基类继承才能具有相同的接口。还是我错了?
  • 您的应用程序是否真的内存不足?许多应用程序无需担心为此进行优化。

标签: c# design-patterns inheritance polymorphism decorator


【解决方案1】:

试试这个:

abstract class Base 
{
    public Base(object val)
    {
        this.Val = val;
    }

    public object Val { get; private set; }
}

这样,您的派生类就不需要自己的字段:

public class Derived : Base
{
    public Derived(object val) : base(val) { }
}

【讨论】:

  • @AtoMerZ 请注意,这仍然在基类中有一个字段;简单地说 - 编译器对我们隐藏它。自动实现的属性具有编译器生成的支持字段。
【解决方案2】:

如果是装饰器,则没有字段:

public override object Val {
    // add any decoration effects here if needed
    get { return tail.Val; }
}

tail 是你正在装饰的东西。


但是,听起来您的意思是继承(而不是装饰)-如果是这样:

abstract class BaseClass {
    protected BaseClass(object val) {...}
}
class ConcreteType : BaseClass {
    public ConcreteType(object val)
        : base(val) { }
}

这里的基类甚至可以处理存储等。

【讨论】:

  • 也许我不太明白。 Base 类有一个字段,因为装饰器继承了 Base 类,所以装饰器也是如此。我可以覆盖 Val 属性,但该字段仍保留在内存中。
  • @AtoMerZ 我很困惑......如果你不希望基类有一个字段,那么就不要有一个字段......让派生类担心它。如果基础没有该字段,它也不需要构造函数 - 只要有一个 public abstract object Value {get;} 就可以了......
  • 正如我在问题中所说,派生类必须初始化val。所以我不得不为基类提供一个构造函数来初始化val。这意味着我需要为该属性分配内存(因为我忘记了私有集是解决方案)。
  • 你好像把装饰器和代理混淆了
  • @ivowiblo 不,我认为不会。装饰器一种对象包装模式。是什么让你觉得我把它弄糊涂了?
猜你喜欢
  • 1970-01-01
  • 2013-04-19
  • 2016-09-28
  • 2015-07-25
  • 2019-02-27
  • 2011-08-31
  • 2016-05-16
  • 2012-06-23
  • 1970-01-01
相关资源
最近更新 更多