装饰器模式是在不更改其接口的情况下向对象添加功能的最佳方法之一。 我经常使用可组合装饰器,并且总是会问自己在功能列表必须可配置时如何正确设计它们。 我不确定我的答案是否正确,但是这里有一些值得深思的地方。
假设我有一个数字列表:
interface Numbers {Iterable<Integer> iterate();
}
现在,我想创建一个仅包含奇数,唯一,正数和排序数的列表。 第一种方法是垂直的 (我刚刚将其命名):
Numbers numbers = new Sorted(new Unique(new Odds(new Positive(new ArrayNumbers(new Integer[] {-1, 78, 4, -34, 98, 4,}))))
);
第二种方法是水平的 (同样,我做了一个名字):
Numbers numbers = new Modified(new ArrayNumbers(new Integer[] {-1, 78, 4, -34, 98, 4,}),new Diff[] {new Positive(),new Odds(),new Unique(),new Sorted(),}
);
看到不同? 第一种方法“垂直”修饰ArrayNumbers
,通过可组合修饰符Positive
, Odds
, Unique
和Sorted
添加功能。
第二种方法引入了新的接口Diff
,该接口通过Positive
, Odds
, Unique
和Sorted
实例实现了迭代数字的核心功能:
interface Diff {Iterable<Integer> apply(Iterable<Integer> origin);
}
对于numbers
用户,这两种方法是相同的。 区别仅在于设计。 哪个更好?何时? 似乎垂直装饰更容易实现,并且更适合于只暴露一些方法的较小对象。
根据我的经验,我总是倾向于从垂直装饰开始,因为它易于实现,但是随着装饰器数量的增加,最终会迁移到水平装饰。
翻译自: https://www.javacodegeeks.com/2015/10/vertical-and-horizontal-decorating.html