2010-11-11 58 views
1

这就是我想要做的事:要使用哪种设计模式来实现“数据扩展器”?

public class DataBuilder { 
    public DataBlock create() { 
    DataBlock block = new DataBlock(); 
    for (Extender extender : this.getExtenders()) { 
     extender.extend(block); 
    } 
    } 
} 

一段时间后:

DataBlock block = new DataBuilder().create(); 

extender将添加一些特定的信息到blockDataBuilder并不想知道这些扩展器的内部结构。目前我的getExtenders()方法查找Extender(在classpath中)的所有子类,并返回它们的实例。

工作正常,但我不喜欢它的外观,在设计方面。也许我可以/应该使用一些模式,使这个构造更灵活?

回答

1

继续阿德里安的答案,我会简单介绍一下它是如何工作的:

让我们假设数据块从名为IDataBlock的接口派生。每个扩展器派生自DataBlockDecorator,派生自IDataBlock,它对DataBlock执行一些操作(接受构造器中的IDataBlock)。这可以让你做类似的事情。

IDataBlock block = new DataBlock(); 
for (DataBlockDecorator extender : this.getExtenders()) { 
    extender.extend(block); 
    block = extender; 
} 

但是,它并没有真正增加以前的灵活性。就此而言,您的原始解决方案已经非常灵活。

+0

诀窍是'this.getExtenders()',它不像应该那样灵活。其余的都是一样的,装饰模式让事情变得更加复杂......就像我看到的那样。对? – yegor256 2010-11-11 12:32:48

+0

@Vincenzo:你错过了一个小而重要的细节。只要您的扩展程序实际上不扩展任何内容,但只执行对象的一次更改,那么您是对的。然而,如果你的扩展器是在对真实对象的调用被执行(想象一个包装器)时扩展对象,那么装饰器模式是正确的方法,因为它增加了更多的灵活性。 – 2010-11-11 12:49:10

+0

@Vincenzo啊,我想我明白你在哪里了。不幸的是,要实例化许多类,您要么必须在某种意义上指定它们的名称,要么使用像您所使用的反射策略。最好你可以希望的是将这个加载封装到某种工厂中,并且可能试图实例化所有实现某个接口(而不是物理类)的类。 – Neil 2010-11-11 13:16:19

0

看看Decorator模式。

+0

你能举一个简单的例子装饰者将如何在我的情况下工作? – yegor256 2010-11-11 11:52:37

+0

@Vincenzo如果我正确理解你的OP,你正在寻找一种模式来添加或编辑块的行为,而不需要将任何关于扩展器内部工作的知识嵌入到构建器中。因此,扩展器是您的块的装饰器。看看上面的维基百科网站,以获得深入的解释和模式的几个例子。 – 2010-11-11 12:22:49

0

装饰模式

interface BlockDeckorator 
{ 
    extend(DataBlock block); 
} 

class FooBlockDecoratorImpl implements BlockDecorator 
{ 
    private BlockDeckorator blockDecorator; 

    public FooBlockDecoratorImpl(BlockDecorator decorator) 
    { 
     this.blockDecorator = decorator; 
    } 

    public void extend(DataBlock block) 
    { 
     blockDecorator(block); 
     // Add my own code to do Foo afterwards (or before) 
    } 
}