“责任链”和“责任链”有什么区别?和“策略”模式?
我提出这个问题是因为另一个问题几天前我在这里问过。
我必须解决一个特定的问题,在收到两次回复后,我意识到两种模式可以帮助解决该问题(以及任何其他类似问题)。
- 责任链
- 策略
我的问题是:
这些模式之间到底有什么区别?
I'm raising this question because of another question I asked here on SO some days ago.
I had to solve an specific problem, and after two replies I got, I realized two patterns can help to solve that problem (and any other similar).
- Chain of Responsibility
- Strategy
My question is:
What exactly is the difference between those patterns?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
他们非常不同。
策略是指拥有一个通用接口,您可以使用它来提供算法的不同实现,或者具有某些共同依赖性的多个算法或逻辑片段。
例如,您的
CollectionSorter
可以支持SortingStrategy
(合并排序、快速排序、冒泡排序)。它们都有相同的界面和用途,但可以做不同的事情。在某些情况下,您可能决定内部确定策略。也许排序器有一些基于集合大小等的启发式方法。大多数时候它确实是从外部注入。这是该模式真正发挥作用的时候:它为用户提供了覆盖(或提供)行为的能力。
这种模式是现在无所不在的控制反转的基础。完成经典模式后,接下来研究一下。
责任链是指拥有一条通常从更详细到更通用的对象链。链条中的每个部分都可以提供答案,但它们的详细程度不同。
流行的 GOF 示例是上下文帮助系统。当您单击桌面应用程序中的某个组件时,会显示哪些帮助?链中的第一项可以为您单击的组件寻求帮助。链中的下一步可以尝试显示整个包含对话框的帮助。接下来是应用程序模块......等等。
看起来您还没有,但应该阅读 GOF“设计模式”经典著作。
They're very different.
Strategy is about having a generic interface which you can use to provide different implementations of an algorithm, or several algorithms or pieces of logic which have some common dependencies.
For instance, your
CollectionSorter
could support aSortingStrategy
(merge sort, quick sort, bubble sort). They all have the same interface and purpose, but can do different things.In some cases you may decide to determine strategy inside. Maybe the sorter has some heuristics based on collection size etc. Most of the time it indeed is injected from outside. This is when the pattern really shines: It provides users the ability to override (or provide) behavior.
This pattern is base of the now-omnipresent Inversion of Control. Study that next once you're done with the classic patterns.
Chain of responsibility is about having a chain of objects which usually go from more detailed to more generic. Each of the pieces in chain can provide the answer, but they have different levels of detail.
Popular GOF example is a context help system. When you click on a component in your desktop app, which help to display? First item in chain could look for help for the very component you clicked. Next in chain could try and display help for the whole containing dialog. Next for the application module... and so on.
Looks like you haven't, but should, read the GOF "Design Patterns" classic.
在责任链中,如果对象无法处理该调用,则每个对象都有责任将调用发送到链中的下一个对象。
在策略中,所有对象都具有相同的接口,但必须有一些外部力量来提供使用哪一个接口。
In Chain of Responsibility, it is each object's responsibility to send the call on to the next object in the chain, if the object cannot handle it.
In Strategy, all objects have the same interface, but some outside force has to supply which one is used.
顾名思义,责任链模式为请求创建接收者对象链。此模式根据请求类型将请求的发送者和接收者解耦。这种模式属于行为模式。在此模式中,通常每个接收器都包含对另一个接收器的引用。
责任链模式表示“通过为多个对象提供处理请求的机会来避免将请求的发送者与其接收者耦合”。例如,ATM 在取款过程中使用责任链设计模式。
策略是一种行为设计模式,可让您定义一系列算法,将每个算法放入单独的类中,并使它们的对象可以互换。
在策略模式中,我们创建代表各种策略的对象和一个其行为根据其策略对象而变化的上下文对象。策略对象改变上下文对象的执行算法。
As the name suggests, the chain of responsibility pattern creates a chain of receiver objects for a request. This pattern decouples sender and receiver of a request based on type of request. This pattern comes under behavioral patterns. In this pattern, normally each receiver contains reference to another receiver.
A Chain of Responsibility Pattern says that just "avoid coupling the sender of a request to its receiver by giving multiple objects a chance to handle the request". For example, an ATM uses the Chain of Responsibility design pattern in money giving process.
Strategy is a behavioral design pattern that lets you define a family of algorithms, put each of them into a separate class, and make their objects interchangeable.
In Strategy pattern, we create objects which represent various strategies and a context object whose behavior varies as per its strategy object. The strategy object changes the executing algorithm of the context object.
大多数模式在代码(甚至 uml)中看起来非常相似,但模式的核心是上下文、职责以及它们想要解决的特定问题,而不是特定的源代码。两者都出于不同的原因解耦不同的事物。
链式模式将发送请求的职责与处理请求的职责分开。可能有许多类可以处理相同类型的请求(这些类通常实现相同的接口),但该模式允许请求从一个类(在链中)传递到另一个类,直到处理程序最适合处理请求的人获取它并负责处理请求(或者直到空处理程序获取它并指示链的末尾)。如果您允许错误的处理程序来处理请求,结果可能“永远”是正确的
。策略是关于处理方法或算法选择。举个例子,你想计算一些样本的平均值。任何算法在给定的上下文中都可能“总是”正确(例如,具有策略的所有类都做相同的事情:计算平均值),但计算平均值的方式或计算平均值的策略因一个类而异,策略模式允许您以解耦的方式选择使用哪种策略。
现在将其与链模式进行比较,其中可能有一个计算平均值的请求,其中有一个处理程序负责计算平均值,并且可能有另一个计算标准差的请求,其中有另一个处理程序负责计算标准差。因此,计算平均值的请求在任何情况下都不会由除最适合的处理程序之外的任何其他处理程序处理。其中,策略中的任何类别都可以计算平均值,如果您不喜欢某个类别计算平均值的方式,您可以将一种策略“交换”为另一种策略。
在源代码中实现这些的方法可能因程序员而异,但应该PTSUT(通过相同的单元测试”)
编辑:
可能会发生链的某些成员责任可以使用策略模式来完成他们的工作
Most patterns look very similar in code (or even uml) but patterns are centrally about context, responsibilities the particular problem they intend to solve rather than a particular source code. both decouples different things and for different reasons.
The chain pattern separates the responsibility of sending a request from the handling of the request. there could be a number of classes that can handle the same type of request (these classes generally implement the same interface) but the pattern allows the request to be passed along from one class (in the chain) to the other until a handler who is most fit to handle the request gets it and is responsible for handling the request (or until a null handler gets it and indicates the end of the chain). If you allow the wrong handler to handle the request, the result may "NEVER" be correct
The strategy is about method of processing or algorithm selection. take example of a case where you want to calculate the average of some samples. Any algorithm may "ALWAYS" be correct in the given context (e.g all classes having a strategy does same thing: calculates the average ), but the way the average is calculated, or the strategy for calculating the average differs from one class to the other, and the strategy pattern allows you to select which strategy to use in a decoupled manner.
now compare this to the chain pattern , where there can be a request for calculating average in which there is one handler that is responsible for computing average and there could be another request to calculate the standard deviation in which there is another handler that is responsible for computing standard deviation. so the request to compute average will not in any situation be handled by any other handler other than the handler most fit. where as, any class in the strategy may calculate the average and if you don't like the way one class calculates average, you can "SWAP" one strategy for the other.
ways of implementing these in source code may differ from programmer to programmer but should PTSUT (pass the same unit test")
Edit:
It could happen that certain members of the chain of responsibility may use strategy pattern to do their work
最显着的区别是实现的语义行为。
责任链
可以将0...ALL
的职责应用于输入,每个职责
决定是否对输入执行操作,然后把它传递下去。这是一种程序模式,因为所有责任都可能适用。一个
策略
有一个且只有一个策略适用于输入。这通常是一种创建模式,因为仅应用单一策略。两者都可以使用
访问者模式
实现为列表
,区别在于当策略
返回时您停止访问真
。策略模式
也可以实现为Map
,其中Key
是一个谓词
,可以决定结束迭代键,然后你就得到Value
这就是你的结果。The most significant difference is a semantic behavior of the implementation.
A
Chain of Responsibility
can have0...ALL
of the responsibilities applied to an input and eachResponsibility
decides if acts on the input and then passes it on. This is a procedural pattern since all responsibilities may be applied.A
Strategy
has one and only one of the strategies apply to an input. This is a usually creational pattern since only a single strategy is applied.Both can be implemented as a
List
using aVisitor Pattern
the difference would be you stop visiting when aStrategy
returnstrue
.A
Strategy Pattern
can also be implemented as aMap
where theKey
is aPredicate
that can decide to end the iteration of the keys and then you just get theValue
and that is your result.您可以将责任链视为策略模式的特例,它更通用。正如 Konrad 所说,您使用基于模式的解决方案解决的问题是不同的。
BTW:你几乎可以在任何 GOF 模式中找到一种策略。
You can consider chain of responsibility as a special case of the strategy pattern, which is more generic. As stated by Konrad the problem you address with the pattern-based solution is different.
BTW: You can find a kind of strategy in almost any GOF pattern.
策略模式:
看看这个 SE 问题的策略示例:
真实世界示例战略模式的
责任链:
要点:
现实世界示例:在公司中,指定的角色在处理采购请求时具有特定的限制。如果具有指定角色的人没有足够的权力来批准采购法案,他会将命令/请求转发给拥有更多权力的继任者。该链将继续下去,直到命令被处理。
请参阅以下有用的 SE 问题/链接
Chain-of-responsibility_pattern
责任链模式 来自 oodesign
chain_of_responsibility 来自 sourcemaking
Strategy pattern:
Have a look at this SE question for Strategy example :
Real World Example of the Strategy Pattern
Chain of Responsibility:
Key points:
Real world example : In a company, a designated role have particular limits to process purchase request. If person with a designated role does not have enough power to approve purchase bill, he will forward the command/request to his successor, who have more power. This chain will continue until the command is processed.
Refer to below useful SE questions/links
Chain-of-responsibility_pattern
Chain-of-responsibility-pattern from oodesign
chain_of_responsibility from sourcemaking
策略模式是一种业务级别模式,是如何实现给定目标/数据结果的标准化接口方式。
责任链更多的是实现模式 - 描述如何处理数据,但不关注什么(策略的目标)。
例如:
假设我们俱乐部有 100 名年轻游泳运动员,每年必须选拔 4 次 10 人队参加常规的全国比赛。
比赛有不同的特点——有些有更多的仰泳比赛,有些有更多的接力比赛等等……这意味着你必须应用不同的团队选择策略。
因此,您有 4 个专用策略,每个事件一个。
在代码中它可能看起来像:
但是如何获得排名呢?
你就征求教练组的意见:
游泳运动员(自评)->生理学家->生物更新训练器->医生->游泳教练->队友->老师->父母... ---->战略/资格委员会
这是一个职责链。顺序很重要...如果没有生理学家的评估,医生就无法评估游泳运动员,如果主教练拒绝游泳运动员,家长的意见并不重要...
排名信息在从一个处理器传递到下一个处理器时会合并,一些数据是对于某些处理器隐藏,其他处理器可以用附加注释装饰...
在这种情况下有趣的是,作为俱乐部的解说员,您可以在两个层面上考虑策略:
但在“设计模式”术语中策略模式只有1。
点2. 规模太大,无法用单一设计模式来分析。
重要的是要记住,在设计模式分析中,您应该关注相当小的功能部分,在这些功能中您可以轻松地识别单个模式并实现它。
当功能块太大时,会自动涉及许多模式及其之间的关系,讨论就会变得混乱,有些人如此专注于某些模式,以至于他们到处都能看到它们。识别设计模式基于缓慢的分析和仔细的问题分解。
Strategy pattern is a business level pattern, a standardized interface way of how to achieve given goals/data results.
Chain of responsibilities is more implementation pattern - describing how you process the data, but not focusing for what (goals of a strategy).
For example:
Let's say we have 100 young swimmers in a club and 4 times a year you must select 10 person team for a regular national competition.
The competitions have different profiles - some have more backstroke races, some more relay races, etc ... what means you must apply different team selection strategy.
So you have 4 dedicated strategies, one for each event.
In the code it could look like:
But how to get the rankings?
You just ask for opinion the coaching staff:
swimmer(self-assessment) -> physiologist -> biological renewal trainer -> doctor -> swimming trainer -> teammates -> teachers -> parents ... ----> strategy/qualifying committee
This is a chain of responsibilities. The order is important ... a doctor cannot assess a swimmer without evaluation from physiologist, parent opinion does not matter if main trainer rejects a swimmer ...
The ranking information is merged while passing from one processor to the next processor, some data are hidden for some processor, other can be decorated with additional notes ...
What is interesting in this case that as a narrator from the club you can think of strategy on two levels:
but in "Design Patterns" terminology the strategy pattern is only 1.
Point 2. is too big to analyze in terms of single design pattern.
It is important to remember that in Design Pattern analysis you should focus on rather small pieces of functionality, where you can easily identify a single pattern and implement it.
When functionality chunk is too big automatically many patterns and relation between them are involved, the discussion becomes chaotic, some guys are so fixated on some patterns that they see them everywhere. Identifying design patterns is based on slow analysis and careful problem decomposition.