【问题标题】:Decorator pattern - Restrict the decorators to specific types of components装饰器模式 - 将装饰器限制为特定类型的组件
【发布时间】:2016-09-16 14:58:33
【问题描述】:

当你的装饰器应用于不兼容的组件时,你会怎么做?

如果您考虑给出的经典示例来说明模式的使用,图形窗口,如果您将滚动条装饰器应用于(例如)对话框会发生什么(“对话框”是具有固定大小的具体窗口组件) ?或者更确切地说,“应该”发生什么? (我认为理想情况下“什么都不会”发生,至少就滚动条装饰对话框的用户在他们的屏幕上看到的内容而言,但我对避免人们做愚蠢事情的策略更感兴趣。)

【问题讨论】:

    标签: design-patterns decorator


    【解决方案1】:

    但我更感兴趣的是避免人们做蠢事的策略

    您可以通过使用marker 接口模式来实现这一点。

    • 定义一个名为Scrollable的接口。
    • 所有支持滚动功能的组件都将实现这个接口。例如,WindowScrollable,因此应该实现此接口。
    • 具体的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 中的自定义属性。

    【讨论】:

    • 如果您拥有想要装饰的类,则此方法有效,但装饰器模式通常用于第三方类。如果您无法控制WindowDialog,并且无法改变Dialog 扩展Window 的事实怎么办?
    • @jaco0646 我相信这是你应该问 OP 的问题。在我看来,“当 your 装饰器应用于不兼容的组件时,你会怎么做?”并且“但是对避免人们做愚蠢事情的策略更感兴趣”表明OP是API的所有者:)。也就是说,客户端代码必须实现一种方法来阻止他们的开发人员做愚蠢的事情。不过,我认为这不是 OP 在这里寻找的东西..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 2012-01-28
    • 2012-02-29
    • 1970-01-01
    • 2020-03-26
    • 2023-04-06
    相关资源
    最近更新 更多