装饰图案浪费内存
Posted
技术标签:
【中文标题】装饰图案浪费内存【英文标题】: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 成员的任何其他副本。 装饰器不存储任何基本成员的副本。它只是存储对装饰对象的引用!? 它也必须从基类继承才能具有相同的接口。还是我错了? 您的应用程序是否真的内存不足?许多应用程序无需担心为此进行优化。 【参考方案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 不,我认为不会。装饰器是一种对象包装模式。是什么让你觉得我把它弄糊涂了?以上是关于装饰图案浪费内存的主要内容,如果未能解决你的问题,请参考以下文章
哪一个更可能浪费更少的内存,一个大内存管理器或几个小内存管理器? [关闭]