以下列方式将比较器应用于列表时,使用的设计模式是什么或这里使用的技术是什么?
Collections.sort(myCollection, new Comparator<MyItem>() {
@Override
public int compare(MyItem item1, MyItem item2) {
return item1.getId().compareTo(item2.getId());
}
});
答案 0 :(得分:9)
TL; DR :
Collections.sort
是一个简单多态替换的示例,无论您是使用功能编程还是面向对象编程来进行此替换。术语策略模式不能与多态或功能编程互换。
我们仍然可以说我们正在将排序Strategy
传递给sort
方法,但没有Context
,它不是策略模式的同义词。
以下列方式将比较器应用于列表时,使用的设计模式是什么或这里使用的技术是什么?
由于此问题已标记为 OOP ,因此此处未使用 OOP 设计模式。这是普通的 Polymorphism 。一些程序员可能称之为策略模式,但我不同意。 策略模式提倡组合而非继承,其中您使用 has-a 关系而非是-a 关系。
一些程序员可能会进一步争辩说我们正在将排序Strategy
传递给Collections.sort
方法,因此这是策略模式;但是,需要承认的是Strategy
是战略模式的组成部分之一。 策略模式的另一个重要组成部分是Context
,它与策略建立 HAS-A 关系。这个组件是策略模式背后的动机的核心,它更喜欢组合而非继承。你不能从整体中脱颖而出,仍然把整个分开的部分称为。您无法从策略模式中取出Context
,仍然可以将剩余部分称为策略模式。
Collections.sort
是一种static
方法,允许您多态替换要在运行时使用的Comparator
实现。
支持材料
让我们看一下来自GoF的战略模式的定义:
将算法封装在对象中是策略的目的 (315)模式。该模式的主要参与者是战略 对象(封装不同的算法)和上下文 他们经营的。合成者是战略;它们封装了不同的格式化算法。 合成是合成器策略的上下文。
...
对象组合提供了一种可行的,更灵活的扩展机制..
现在应该清楚,多态性和策略模式之间存在细微差别。 策略模式讨论了上下文,它使用上面粗体中突出显示的组合。 Collections
类未与 Comparator 建立组合关系。此外,策略模式的class diagram显示了一个名为 Context 的组件,它构成了策略接口。
这个问题被标记为 OOP ,但如果我们想谈谈Collections.sort
在函数式编程范式中所代表的模式,我会说它代表函数式编程。 (如果我不得不将一个函数传递给一个方法到一个OOP模式,我会说它比策略模式更接近(不完全)类似于命令模式
相关内容:Does Functional Programming Replace GoF Design Patterns?
答案 1 :(得分:3)
Collections.sort()使用Strategy模式。
答案 2 :(得分:1)
我认为最好先看另一种形式的
Collections.sort(myCollection)
哪个算法无法在运行时比较项目。在这种方法中,它使用通过Item的继承提供的算法(通过实现Comparable接口)。不是一个直接的方式,但如果我们看一点灵活,这是模板模式。此方法使用继承和项目的行为在运行时不能更改。
但是第二种形式
Collections.sort(myCollection,comparison-algorithm)
我们在运行时发送不同于模板模式(继承)的行为,这在我们使用提供运行时和可更改行为时是可能的。这是战略模式中最重要的部分。
有人可能会问这里策略模式的组成部分在哪里?组合不仅仅是保持算法,以便在需要时使用它。但是在这种情况下,每当需要算法时,它都作为参数传递,因为Collections类是一个用于不同目的的Utils类,而不是我们在Strategy Pattern原始版本中看到的Context类。