jjzjj

c# - 桥梁模式与策略模式

coder 2024-06-03 原文

我知道,这个问题被问过很多次了,但我做了一些研究,但还是没弄明白,也许你能帮我解决这个问题: 正如多次声明的那样,UML 几乎是相同的。此外,实现和想法或多或少是相同的:您定义一个接口(interface),而不是子类型,它封装了一些逻辑并让它传递给抽象。 所以,即使是 Microsoft 博客专家

https://blogs.msdn.microsoft.com/gyanjadal/2015/01/05/difference-between-strategy-and-bridge-patterns/说:

The simple answer is “They are similar but different”. The implementations are similar but the intentions are different. To give an analogy, a city bus and school bus are both similar vehicles, but they are used for different purposes. One is used to transport people between various parts of the city as a commuter service. The other is used for transporting kids to schools.

“如果它听起来像一只鸭子,看起来像一只鸭子,但它打算成为一只天鹅,那么它可以是它们中的任何一个”,这是我在这里读到的。

因为还是没看懂,所以就深挖一下:

https://social.msdn.microsoft.com/Forums/en-US/08775d39-2de0-4598-8872-df21f681b7b3/strategy-vs-bridge-patterns?forum=architecturegeneral

此线程也没有添加任何新内容,除了:

They both look the same on the surface to me as well. The main difference I see is the fact that in the Bridge pattern, the abstraction is PART OF the object, but in the Strategy pattern the abstraction is performed BY the object.

但是,如果我们阅读策略的定义:

Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.

没有定义策略是如何应用的。它也可以很容易地成为抽象的接口(interface),与 LINQ-Orderby 等常见的策略实现完全相同。

关于该主题的另一个兴趣点在这里:

http://game-engineering.blogspot.ch/2008/07/bridge-pattern-vs-strategy-pattern.html

本次类(class)的主要部分:

You say "Strategy" when you want to vary behavior, and you do so not by writing different objects but by introducing a class heirarchy. You say "Bridge" when you expect that you will vary both the interface and the implementation. In both cases you're providing flexibility for a changing implementation; in a Bridge, you're also expecting the interface to change.

这可能是主要区别吗?由于实现者和抽象是如此松耦合,我可以更改实现者的接口(interface)而抽象不必关心?这听起来很合理,但是因为它们以某种方式连接,所以抽象也不会改变吗?这不会破坏信息隐藏和 DRY 等所有其他原则吗?

我还查看了很多示例,为了位置的原因我没有在此处添加这些示例,而且我找不到其中任何一种模式的示例,我无法更改以适应另一种模式。无论是通过接口(interface)属性还是仅通过参数。

我在这里错过了什么吗?可能有人有“我想使用 Strategy,但 Bridge 确实更适合”的真实示例,或者反之亦然,例如?

编辑:为什么我要为这个主题(再次)证明一个自己的线程?首先,上述线程的公认答案如下

As I understand it, you're using the strategy pattern when you're abstracting behavior that could be provided from an external source (eg. config could specify to load some plugin assembly), and you're using the bridge pattern when you use the same constructs to make your code a bit neater. The actual code will look very similar - you're just applying the patterns for slightly different reasons.

我在前面的解释中已经提供了,从外部源抽象行为正是 Strategy- and Bridge-Pattern 的定义。

还有

and you're using the bridge pattern when you use the same constructs to make your code a bit neater.

策略模式还使代码更整洁,因为它抽象了整个构建 block ,从而大大加强了代码。

我认为任何阅读了整个主题的人都会看到,除了这两句话之外,这个主题还有更多内容。

最佳答案

桥接模式的维基百科 UML 图:

查看我在链接问题中的回答以了解基本差异:

What is the difference between the bridge pattern and the strategy pattern?

主要区别:抽象和实现可以独立更改

关于您的其他查询:

Is this probably the main-difference? Since the Implementor and the Abstraction are so loose coupled, I can change the Interface of the Implementor and the Abstraction doesn't have to care? That sounds reasonable, but wouldn't then have the Abstraction to change as well, since they are kindahow connected?

看看下面的代码示例@

When do you use the Bridge Pattern? How is it different from Adapter pattern?

尽管该示例是用 java 编写的,但对于 c# 开发人员来说也很容易理解。

在链接示例中:

Vehicle            : Abstraction
Car                : Re-defined Abstraction
Truck              : Re-defined Abstraction
Implementor        : GearShifter
ConcreteImplementor: ManualGearShifter  
ConcreteImplementor: AutoGearShifter 

主题演讲:

  1. 现在 VehicleGearShifter 可以独立改变。

  2. 如果 Vehicle 发生变化,则只需更改 CarTruck

  3. 如果 GearShifter 改变,只有 ManualGearShifterAutoGearShifter 需要改变。

  4. 由于 Vehicle(抽象)通过组合包含 GearShifter(实现),因此 GearShifter 的更改不会影响 Vehicle

  5. 由于GearShifter(实现者)不包含或引用Vehicle(抽象),抽象的变化不会影响实现。

编辑:

桥接模式呈现两个正交的类层次结构 - 一个用于抽象,一个用于实现,它们可以独立更改而不依赖于其他。

关于c# - 桥梁模式与策略模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38814624/

有关c# - 桥梁模式与策略模式的更多相关文章

  1. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  5. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  6. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  7. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  8. ruby-on-rails - environment.rb 中设置的常量在开发模式中消失 - 2

    了解Rails缓存如何工作的人可以真正帮助我。这是嵌套在Rails::Initializer.runblock中的代码:config.after_initializedoSomeClass.const_set'SOME_CONST','SOME_VAL'end现在,如果我运行script/server并发出请求,一切都很好。然而,在我的Rails应用程序的第二个请求中,一切都因单元化常量错误而变得糟糕。在生产模式下,我可以成功发出第二个请求,这意味着常量仍然存在。我已通过将以上内容更改为以下内容来解决问题:config.after_initializedorequire'some_cl

  9. Ruby:标准递归模式 - 2

    我经常迷上ruby​​的一件事是递归模式。例如,假设我有一个数组,它可能包含无限深度的数组作为元素。所以,例如:my_array=[1,[2,3,[4,5,[6,7]]]]我想创建一个方法,可以将数组展平为[1,2,3,4,5,6,7]。我知道.flatten可以完成这项工作,但这个问题是作为我经常遇到的递归问题的一个例子-因此我试图找到一个更可重用的解决方案。简而言之-我猜这种事情有一个标准模式,但我想不出任何特别优雅的东西。任何想法表示赞赏 最佳答案 递归是一种方法,它不依赖于语言。您在编写算法时要考虑两种情况:再次调用函数的情

  10. ruby - 在 Ruby 中查找多个正则表达式匹配的模式和位置 - 2

    这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo

随机推荐