【发布时间】:2016-09-16 14:58:33
【问题描述】:
当你的装饰器应用于不兼容的组件时,你会怎么做?
如果您考虑给出的经典示例来说明模式的使用,图形窗口,如果您将滚动条装饰器应用于(例如)对话框会发生什么(“对话框”是具有固定大小的具体窗口组件) ?或者更确切地说,“应该”发生什么? (我认为理想情况下“什么都不会”发生,至少就滚动条装饰对话框的用户在他们的屏幕上看到的内容而言,但我对避免人们做愚蠢事情的策略更感兴趣。)
【问题讨论】:
当你的装饰器应用于不兼容的组件时,你会怎么做?
如果您考虑给出的经典示例来说明模式的使用,图形窗口,如果您将滚动条装饰器应用于(例如)对话框会发生什么(“对话框”是具有固定大小的具体窗口组件) ?或者更确切地说,“应该”发生什么? (我认为理想情况下“什么都不会”发生,至少就滚动条装饰对话框的用户在他们的屏幕上看到的内容而言,但我对避免人们做愚蠢事情的策略更感兴趣。)
【问题讨论】:
但我更感兴趣的是避免人们做蠢事的策略
您可以通过使用marker 接口模式来实现这一点。
Scrollable的接口。Window 是 Scrollable,因此应该实现此接口。ScrollDecorator 实现将具有Scrollable 实例变量和一个接受Scrollable 参数的构造函数。ScrollDecorator 构造函数采用Scrollable 参数,您现在可以限制ScroallDecorator 只能装饰Scrollable 的实例。由于这是一个与语言无关的问题,因此“接口”和“实现”这两个词不应与 Java 编程语言相关联,而是与一般定义相关联。也就是说,这是上面在 Java 中讨论的要点的编码版本:
让我们先看看解决方案的最终期望状态:
Component window = new ScrollDecorator(new Window());//should be allowed
Component dialog = new ScrollDecorator(new Dialog());//should not be allowed.
尝试使用滚动条装饰对话框将导致编译错误。现在让我们看看使这成为可能的类:
组件
public interface Component {
public void load();
}
可滚动(标记界面)
public interface Scrollable extends Component {
}
混凝土构件(窗)
public class Window implements Scrollable {
@Override
public void load() {
//code for drawing a window.
}
}
具体组件(对话框)
class Dialog implements Component {
@Override
public void load() {
//code for drawing a dialog.
}
}
滚动装饰器
public class ScrollDecorator implements Component {
private Scrollable scrollable;
public ScrollDecorator(Scrollable scrollable) {
this.scrollable = scrollable;
}
@Override
public void load() {
scrollable.load();
//code for drawing a scrollbar over the scrollable component
}
}
可用于实现此目的的其他语言特定选项是 Java 中的注释或 .NET 中的自定义属性。
【讨论】:
Window 和Dialog,并且无法改变Dialog 扩展Window 的事实怎么办?