Decorator设计模式:为什么调用链中的函数而不调用循环中的函数
Decorator design pattern: why call functions in chain but not in loop?
在装饰器设计模式中,我们将相同类型的对象封装在一起,然后在链中调用它们中的相同函数。这允许添加一个功能。现在,我们为什么不做同样的事情,不是在链中,而是在循环中。我的意思是,我们可以将所有对象存储在一个向量中(map?),如果调用了一个函数,我们就可以将该调用委托给向量的每个元素。购买这样做我们将有甚至的优势,例如如果我想访问(获取状态)一个特定的装饰器,我可以直接访问它,而不向接口添加公共函数,这样所有的装饰器都应该重写,但在大多数情况下,该函数不应该做任何事情。例如,在窗口和滚动条的经典示例中,如果我不想知道水平滚动条是否被锁定,那么我需要向WindowDecorator
添加isHorizontalScrollBarLocked函数,这对垂直滚动条和许多其他装饰器来说也没有意义。
编辑(添加代码以明确我所说的内容):
// the Window interface class
public interface Window {
public void draw(); // draws the Window
public String getDescription(); // returns a description of the Window
}
// extension of a simple Window without any scrollbars
class SimpleWindow implements Window {
public void draw() {
// draw window
}
public String getDescription() {
return "simple window";
}
}
// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
protected Window decoratedWindow; // the Window being decorated
public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
public void draw() {
decoratedWindow.draw(); //delegation
}
public String getDescription() {
return decoratedWindow.getDescription(); //delegation
}
}
// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
@Override
public void draw() {
super.draw();
drawVerticalScrollBar();
}
private void drawVerticalScrollBar() {
// draw the vertical scrollbar
}
@Override
public String getDescription() {
return super.getDescription() + ", including vertical scrollbars";
}
}
// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}
@Override
public void draw() {
super.draw();
drawHorizontalScrollBar();
}
private void drawHorizontalScrollBar() {
// draw the horizontal scrollbar
}
@Override
public String getDescription() {
return super.getDescription() + ", including horizontal scrollbars";
}
}
public class DecoratedWindowTest {
public static void main(String[] args) {
// create a decorated Window with horizontal and vertical scrollbars
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator (new SimpleWindow()));
// print the Window's description
System.out.println(decoratedWindow.getDescription());
}
}
现在我想知道decoratedWindow
的水平滚动条是否被锁定。我该怎么办?我需要在Window
中添加isHorizontalScrollBarLocked
公共函数,并在HorizontalScrollBarDecorator
和所有其他实现Window
的类(在VerticalScrollBarDecorator
WindowDecorator
中)中重写它,对吗?
另一方面,我可以创建一个立面,它将代表我的窗户。在该facade中,我将有一个Window
对象的列表,这些对象将是SimpleWindow
、VerticalScrollBarDecorator
、HorizontalScrollBarDecorator
等。如果用户将调用facade的函数draw
,我将在循环中调用列表中Window
s的所有draw
函数。否则,如果用户仅在HorizontalScrollBarDecorator
对象上调用isHorizontalScrollBarLocked
。
您建议的对decorator模式的更改效果不佳。可以说,您想要实现的facade并没有真正"装饰"任何功能。让我解释一下。。。
考虑一个场景,您希望使用BufferedWriter
将字节写入输出流。BufferedWriter
的职责是等待足够的字节积累,然后再执行其昂贵的操作——写IO。它通过将几个写操作组合成批来decorates
是一个正常的流。
如果您有一个facade,它在decorator链中一直被委托调用,那么BufferedWriter
有什么用?facade并不真正知道BufferedWriter
处于什么状态,因此它不能调用是否一直执行链。
- 函数调用中参数的顺序重要吗
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 变量没有改变?通过向量的函数调用
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 是否有C++编译器选项允许激进地删除所有函数调用,并将参数传递给具有空体的函数
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 模板函数调用
- 获取从C++中同一类中的构造函数调用的方法返回的值
- 析构函数调用
- 成员函数调用和C++对象模型
- 使用共享指针的函数调用,其对象应为 const
- C++:编译时检查匹配的函数调用对?
- 函数调用C++中的参数太少
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 返回指向对象的指针的函数调用是否为 prvalue?
- C++ 如何重载 [] 运算符并进行函数调用
- 代码的效率. 转到和函数调用
- 是同一作用域的函数部分中的函数调用
- 如何封装一个函数,以便它只能由同一类中的一个其他函数调用?
- 类型擦除的std::function与虚拟函数调用的开销