我一直在经历Head First Design Patterns(最近刚刚进入)并且我正在阅读关于策略模式的内容,我想到它可能是一种很好的方式来实现计算税收等的常用方法.我在工作中使用的特定对象,但我有一个问题.
这就是我的想法:
public interface ITax
{
decimal ProvincialTaxRate { get; set; } // Yes, I'm Canadian :)
decimal CalculateTax(decimal subtotal);
}
public SaskatchewanTax
{
public decimal ProvincialTaxRate { get; set; }
public SaskatchewanTax()
{
ProvincialTaxRate = new decimal(0.05f);
}
public decimal CalculateTax(subtotal)
{
return ProvincialTaxRate * subtotal + FederalTaxRate * subtotal;
}
}
public OntarioTax
{
public decimal ProvincialTaxRate { get; set; }
public OntarioTax()
{
ProvincialTaxRate = new decimal(0.08f);
}
public decimal CalculateTax(decimal subtotal)
{
return …
Run Code Online (Sandbox Code Playgroud) 我现在将关闭这个(我想没有更多的反馈),并试着总结一下我的理解
我正在努力清楚地了解战略模式,并且我问自己,策略取决于上下文是好还是坏.
让我们采取以下经典实现
//The strategy
interface IStrategy
{
void Execute();
}
class ConcreteStrategyA : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyA.Execute()" );
}
}
class ConcreteStrategyB : IStrategy
{
public void Execute()
{
Console.WriteLine( "Called ConcreteStrategyB.Execute()" );
}
}
//The context
class Context
{
IStrategy strategy;
// Constructor
public Context(IStrategy strategy)
{
this.strategy = strategy;
}
public void UpdateContext(IStrategy strategy)
{
this.strategy = strategy;
}
public void Execute()
{
strategy.Execute();
}
}
Run Code Online (Sandbox Code Playgroud)
我见过的所有例子都有非常简单的策略,它们采用基本参数(例如整数).我想知道的是,如果策略使用Context来完成工作,那么是否存在问题.
它会给出类似的东西
//The …
Run Code Online (Sandbox Code Playgroud) 有时在使用策略模式时,我发现一些算法实现不需要相同的参数列表.
例如
public interface Strategy{
public void algorithm(int num);
}
public class StrategyImpl1 implements Strategy{
public void algorithm(int num){
//num is needed in this implementation to run algorithm
}
}
public class StrategyImpl2 implements Strategy{
public void algorithm(int num){
//num is not needed in this implementation to run algorithm but because im using same
strategy interface I need to pass in parameter
}
}
Run Code Online (Sandbox Code Playgroud)
我应该使用不同的设计模式吗?
我知道,这个问题被多次询问,但我做了一些研究,但仍然没有得到它,可能你可以帮助我:正如很多次说的那样,UML几乎是一样的.此外,实现和想法或多或少相同:您可以定义一个Interface,而不是子类型,它封装了一些逻辑,让它传递给一个抽象.所以,即使是微软博客的人
简单的答案是"它们相似但不同".实现类似但意图不同.举一个类比,城市公交车和校车都是类似的车辆,但它们用于不同的目的.一种用于在城市的各个部分之间运送人员作为通勤服务.另一个用于将孩子送到学校.
"如果它看起来像一只鸭子,看起来像一只鸭子,但它打算成为一只天鹅,它可以是其中之一",这就是我在这里读到的.
因为我还没有得到它,所以我深入挖掘:
此线程也不添加任何新内容,除了:
它们在表面上看起来也一样.我看到的主要区别在于,在Bridge模式中,抽象是对象的PART,但在Strategy模式中,抽象是由对象执行的.
但是,如果我们阅读战略的定义:
定义一系列算法,封装每个算法,并使它们可互换.策略允许算法独立于使用它的客户端.
没有任何定义,如何应用该战略.它也可以很容易地成为摘要上的接口,与LINQ-Orderby等常见的策略实现完全相同.
关于这个主题的另一个兴趣是:
http://game-engineering.blogspot.ch/2008/07/bridge-pattern-vs-strategy-pattern.html
这个话题的主要部分:
当你想要改变行为时,你会说"策略",而你不是通过编写不同的对象而是通过引入类层次来实现.当您希望改变界面和实现时,您会说"Bridge".在这两种情况下,您都可以为不断变化的实施提供灵活性; 在Bridge中,您还希望界面能够改变.
这可能是主要区别吗?由于执行器和抽象是如此松散耦合,我可以改变执行器的接口,抽象不必关心?这听起来很合理,但是由于它们是有联系的,所以也不会有抽象改变吗?这不会破坏信息隐藏和DRY等所有其他原则吗?
我还看了很多例子,我不会为了这个地方而添加这些例子,我找不到这些模式的例子,我无法改变以适应另一个.无论是通过Interface-Property还是参数.
我在这里错过了吗?可能任何人都有一个真实生活的例子"我想使用策略,但Bridge确实更合适",反之亦然,例如?
编辑:为什么我为这个主题辩护(再次)?首先,所提到的线程的接受答案如下
据我了解,当你抽象出可以从外部源提供的行为时(例如,config可以指定加载一些插件程序集),你正在使用策略模式,并且当你使用时你正在使用桥接模式相同的结构使你的代码更整洁.实际的代码看起来非常相似 - 你只是因为略有不同的原因而应用这些模式.
我在之前的解释中已经提到,外部源的抽象行为正是Strategy-和Bridge-Pattern的定义.
也
当你使用相同的结构使你的代码更整洁时,你正在使用桥接模式.
此外,策略模式使代码更整洁,因为它将整个构建块抽象出来,从而使代码收紧了很多.
我想任何阅读整个主题的人都会看到,这个主题的内容比这2个句子更多.
我如何获得microsoft unity来"构造"给定接口类型的类列表.
很简单的例子:
List<IShippingCalculation> list = new List<IShippingCalculation>();
list.Add(new NewYorkShippingCalculation());
list.Add(new FloridaShippingCalculation());
list.Add(new AlaskShippingCalculation());
//Not What I want
public void calcship(List<IShippingCalculation> list)
{
var info = new ShippingInfo(list);
info.CalculateShippingAmount(State.Alaska)
}
//Somehow in unity, must i do this for all the concrete classes?
//how does it know to give a list.
Container.RegisterType<IShippingInfo,new AlaskaShippingCalculation()>();??
//What I want
public void calcship(IShippingInfo info)
{
info.CalculateShippingAmount(State.Alaska)
}
Run Code Online (Sandbox Code Playgroud)
谢谢!
我正在学习设计模式并试图遵循Go4书.在页面:179,在装饰模式章节中,有一行说
"通过将策略的数量从一个扩展到一个开放式列表,我们可以递归地实现与嵌套装饰器相同的效果."
我没有得到这个声明.
策略侧重于拥有独立的算法,这些算法可以动态设置,并且不太了解它们所设置的客户端.
而装饰者并不完全独立于他们装饰的客户.实际上,它们与它们装饰的对象具有相同的超类型.
我在这里错过了一点吗?
必须是一个"四人帮"策略的类是完全无状态的(即没有字段)还是它可以包含不可变状态(即最终字段)?
我知道我做得不对,但我也知道有办法做到这一点.我试图尽可能地通用和抽象,否则我的代码将变得非常混乱.所以我在这里使用策略模式作为GetAggregateClient()方法.
我想要一个名为AbstractAggregate的抽象类,以便它使用泛型.将使用的类型是一系列数据类,即BlogItem,ResourceItem和AskItem.这些数据类都继承自ListItem.
这就是背景信息.这里的问题是我希望GetAbstractAggregate()返回一个实现AbstractAggregate的客户端类的实例,其中包含根据传入的枚举指定的项目类型.但是,我不能返回"AbstractAggregate".编译器不会让我这样,因为AbstractAggregateFactory类不是通用的.
有没有人有最好的方法来做到这一点?
非常感谢.
public static class AggregateHelper
{
public enum AggregateTypes { TankTruckBlog, AskTankTruck, Resources }
}
public static class AbstractAggregateFactory
{
public static AbstractAggregate<T> GetAggregateClient(AggregateHelper.AggregateTypes type)
{
switch (type)
{
case AggregateHelper.AggregateTypes.AskTankTruck:
return new AskTankTruckAggregate<AskItem>();
case AggregateHelper.AggregateTypes.TankTruckBlog:
return new TankTruckBlogAggregate<BlogItem>();
case AggregateHelper.AggregateTypes.Resources:
return new ResourcesAggregate<ResourceItem>();
default:
throw new AggregateDoesNotExistException();
}
}
}
public abstract class AbstractAggregate<T>
{
public abstract List<T> GetAggregate(Guid[] resourcetypes);
public abstract T GetSingle(string friendlyname);
}
public class AskTankTruckAggregate<T> : AbstractAggregate<T>
{
//not implemented yet …
Run Code Online (Sandbox Code Playgroud) 我已经学会了这两种模式但却不理解这两种模式之间的差异.
我不知道场景,何时何地使用这些模式.
任何人都可以解释差异和用例吗?
我正在尝试为这种旅行者问题实施一种简单而有效的算法(但这不是"旅行推销员"):
A traveller has to visit N towns, and:
1. each trip from town X to town Y occurs once and only once
2. the origin of each trip is the destination of the previous trip
Run Code Online (Sandbox Code Playgroud)
所以,如果你有例如A,B,C镇,
A->B, B->A, A->C, **C->A, B->C**, C->B
Run Code Online (Sandbox Code Playgroud)
不是解决方案,因为你不能做C-> A然后B-> C(你需要A->B
介于两者之间),而:
A->B, B->C, C->B, B->A, A->C, C->A
Run Code Online (Sandbox Code Playgroud)
是一个可接受的解决方案(每个目的地是下一次旅行的起源).
以下是Java中的插图,例如4个城镇.
ItineraryAlgorithm
是提供回答问题的算法时实现的接口.该main()
如果更换方法将测试你对重复算法new TooSimpleAlgo()
通过new MyAlgorithm()
.
package algorithm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Traveller {
private static …
Run Code Online (Sandbox Code Playgroud) strategy-pattern ×10
c# ×4
java ×2
algorithm ×1
bridge ×1
generics ×1
oop ×1
refactoring ×1
stateless ×1