动态创建装饰链

时间:2011-11-09 17:22:13

标签: c# .net design-patterns decorator

我有一个最初创建的装饰链:

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

这些装饰器中的每一个都会查找数据库以获取计算中使用的一段数据

但是,并非每次都会使用所有这些装饰器。因此,可能存在不返回任何内容的冗余数据库调用

所以我认为最好根据哪些用来动态创建装饰器链

e.g。

如果我有一个代表每个人使用的bool:

bool useTypeA;
bool useTypeB;
bool useTypeC;

我能以某种方式动态构建必要的链吗?

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

3 个答案:

答案 0 :(得分:4)

是的,现在您需要了解Builder Pattern

答案 1 :(得分:0)

我假设数据库查找是在decarators的构造函数中完成的,它们不会被推迟吗?是否可以设计装饰器,只要他们确实需要db中的值,就可以进行数据库查找?

答案 2 :(得分:0)

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

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);
}

请注意,如果订单很重要,您需要了解将项目添加到列表中的顺序。