2011-11-09 43 views
3

我有一个看起来像这样最初创建时,装饰链:动态创建的装饰链

IType calculator = new TypeADecorator(
          new TypeBDecorator(
            new TypeCDecorator(
             new MyCalculator()))); 

每个装饰确实数据库查找得到一个数据,其在计算中使用的

但是,并不是所有这些装饰器都会被使用。因此,将有可能是多余的数据库调用返回什么

所以我想它会更好地动态地创建基于哪些不习惯于

装饰链如

如果我不得不表示被使用的每一个布尔值:

bool useTypeA; 
bool useTypeB; 
bool useTypeC; 

我将能够以某种方式动态地构造所需链?

请记住,它很有可能在应用程序的整个生命周期中添加其他装饰器,所以我想提出一些相当灵活的东西。此外,虽然这里只有三个装饰器,但实际上目前大约有8个使用了

+0

你能提供更多的细节吗?你如何决定使用什么装饰器? –

+0

我可以从当前范围内的各种事情中解决问题。然而,这并不重要 - 正如我所说 - 只是假设有一些bools告诉你应该使用哪个。我对动态构建链的机制感兴趣。我是否需要使用反射/活化剂 - 或者是否有一种更加轻松的方式等等 – ChrisCa

+0

我会存储一个字典>并且只是遍历该字典一次 –

回答

0

我假设数据库查找是在decarators的构造函数中完成的,它们不会被延迟吗?是否有可能设计你的装饰器的方式,他们做数据库查询时,他们真的需要从数据库的价值?

+0

这是一种可能性。还有一个我考虑过。 - 而不是在每个装饰器中查看是否应该使用它。我认为最好先提前一次,然后动态构建链。 – ChrisCa

3

是的,现在您需要阅读有关Builder Pattern

+0

我无法完全理解这会有什么帮助。你是否认为每个装饰器组合都有不同的抽象构建器具体实现?考虑到这个连锁店目前长达8年并且可能增长,这将是很多建筑商。你介意详细介绍一下吗? – ChrisCa

0

有点棘手的部分只是因为你使用你的构造函数来装饰(包装/附加)内部对象。如果你有一个装饰(ITYPE内)方法那么可以使用这个简单的代码:

List<IType> decorators = new List<IType>(); 

if (useTypeA) 
    decorators.Add(new TypeADecorator()); 
if (useTypeB) 
    decorators.Add(new TypeBDecorator()); 
if (useTypeC) 
    decorators.Add(new TypeCDecorator()); 
if (useTypeD) 
    decorators.Add(new TypeDDecorator()); 


IType calculator = new MyCalculator(); 

foreach (IType dec in decorators) 
{ 
    calculator = dec.Decorate(calculator); 
} 

为了使基于构造函数的方法,使用此:

List<Type> decoratorTypes = new List<Type>(); 

if (useTypeA) 
    decoratorTypes.Add(typeof(TypeADecorator)); 
if (useTypeB) 
    decoratorTypes.Add(typeof(TypeBDecorator)); 
if (useTypeC) 
    decoratorTypes.Add(typeof(TypeCDecorator)); 
if (useTypeD) 
    decoratorTypes.Add(typeof(TypeDDecorator)); 

IType calculator = new MyCalculator(); 

foreach (Type decType in decoratorTypes) 
{ 
    calculator = Activator.CreateInstance(decType, calculator); 
} 

注意,如果订单事宜,您需要了解将项目添加到列表中的订单。

+0

Activator.CreateInstance比简单的ctor慢10-20倍,但它在这种情况下不会带来任何好处 –

+0

@Hohhi我喜欢'Decorate'版本,但原来的帖子显示,装饰对象需要被解除对象传递给构造函数。所以Activator。CreateInstance版本以我的第一个样本没有的方式实现。 – tcarvin