Phi*_*ter 43
来自维基百科的装饰模式文章:
在面向对象的编程中,装饰器模式是一种设计模式,允许动态地将新/附加行为添加到现有对象.
在完全构建后,没有必要向披萨添加配料.你不要吃半个披萨,然后再添加一个披萨.
换句话说,Builder Pattern可以很容易地构造一个在构造时可以在独立方向上扩展的对象,而Decorator Pattern允许您在构造时间之后向对象添加功能扩展.使用装饰器模式构造对象是不好的,因为它使对象处于不一致(或至少是不正确的)状态,直到所有必需的装饰器都到位 - 类似于使用setter指定可选构造函数参数的JavaBean问题.
Emi*_*l H 21
你混淆了两件截然不同的事情.GoF将Builder分类为创建模式,而Decorator是结构模式.它们描述如下(Gamma等,第1页):
构建器(97)将复杂对象的构造与其表示分开,以便相同的构造过程可以创建不同的表示.
装饰器(175)动态地将附加职责附加到对象.装饰器为子类化提供了灵活的替代扩展功能.
注意强调装饰器.它是子类化的灵活替代方案.子类化用于建模is-a关系.奶酪不是披萨.披萨由许多成分组成,通常使用成分建模.
建造者模式在这里是相关的,因为存在如此大量的成分,需要以标准化的方式构建它们.
为了获得装饰器的真实示例,我最近想在我的java应用程序中记录使用jdbc执行的查询.我通过实现一个名为LoggingConnection的类来完成此操作,该类扩展了Connection接口.
public class LoggingConnection implements Connection
{
public static class LogEntry
{
public String sql;
public int invocationCount;
public double avgTime;
public double maxTime;
}
private Connection delegate;
private Map<String, LogEntry> log;
public LoggingConnection(Connection delegate)
{
this.delegate = delegate;
this.log = new HashMap<String, LogEntry>();
}
public Map<String, LogEntry> getLog()
{
return log;
}
@Override
public void clearWarnings()
throws SQLException
{
delegate.clearWarnings();
}
@Override
public void close()
throws SQLException
{
delegate.close();
}
// forwarding declarations to all other methods declared in the interface
...
}
Run Code Online (Sandbox Code Playgroud)
这允许我传递连接的具体实现,并在运行时扩展其功能.子类化在此上下文中会有问题,因为您不一定知道实际返回的连接对象.这是因为它是使用DriverManager工厂为您构建的:
Connection conn = DriverManger.getConnection(dsn);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,conn对象是驱动程序中包含的实现,我基本上不知道它的名称.装饰器方法的责任在于我不必知道,并且它与特定实现无关.
让我们来看看Builder和Decorator的关键特性.
建造者 :(创作模式)
装饰者 :(结构模式)
何时使用装饰器:
回到您的查询:
生成器是比萨饼的正确创作模式.披萨最初是用强制性成分制作的(面包等).奶酪,意大利辣香肠,培根是可选配料,但在制作过程中它们仍然可以成为比萨饼的一部分.
Decorator对于在已创建的对象的运行时添加动态职责非常有用.
例如:
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File("a.txt")));
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅以下帖子:
归档时间: |
|
查看次数: |
15315 次 |
最近记录: |