装饰器模式 是在不更改其接口的情况下向对象添加功能的最佳方法之一。我经常使用可组合的装饰器,当功能列表必须是可配置的时,我总是问自己如何正确地设计它们。我不确定我的答案是否正确,但这里有一些值得深思的地方。
假设我有一个数字列表:
interface Numbers {
Iterable<Integer> iterate();
}
现在我想创建一个列表,它只包含奇数、唯一、正数和已排序的数字。第一种方法是 垂直的 (这个名字是我编的):
interface Numbers {
Iterable<Integer> iterate();
}
第二种方法是 横向的 (同样是我编的名字):
interface Numbers {
Iterable<Integer> iterate();
}
看到不同?第一种方法“垂直”装饰
ArrayNumbers
,通过可组合装饰器
Positive
、
Odds
、
Unique
和
Sorted
添加功能。
第二种方法引入了新的接口
Diff
,它通过
Positive
、
Odds
、
Unique
和
Sorted
的实例实现了迭代数字的核心功能:
interface Numbers {
Iterable<Integer> iterate();
}
对于
numbers
的用户,两种方法都是相同的。区别仅在于设计。哪个更好,什么时候?垂直装饰似乎更容易实现,更适合只暴露几个方法的较小对象。
至于我的经验,我总是倾向于从垂直装饰开始,因为它更容易实现,但最终当装饰器的数量开始增长时迁移到水平装饰。