C#实现策略模式

场景:有一个喜欢吃饺子,他有三种不同的方式去吃,蒸饺子,煮饺子,煎饺子,想要用策略模式来设计这个场景,怎么弄?

1.复习简单工厂模式

具体的代码:

EatMethod.cs

public class EatMethod { public virtual void Eat() { Console.WriteLine("This is the base class!"); } }

Steamed.cs

class Steamed : EatMethod { public override void Eat() { Console.WriteLine("This is steamed dumplings!"); } }

Boiled.cs

class Boiled : EatMethod { public override void Eat() { Console.WriteLine("This is boiled dumplings!"); } }

Fried.cs

class Boiled : EatMethod { public override void Eat() { Console.WriteLine("This is boiled dumplings!"); } }

EatFactory.cs

public static class EatFactory { public static EatMethod CreateEatMethod(string eatMethod) { EatMethod eat = null; switch (eatMethod) { case "Steamed": eat = new Steamed(); break; case "Boiled": eat = new Boiled(); break; case "Fried": eat = new Fried(); break; default: break; } return eat; } }

Program.cs

class Program { static void Main(string[] args) { EatMethod eat = EatFactory.CreateEatMethod("Steamed"); eat.Eat(); eat = EatFactory.CreateEatMethod("Boiled"); eat.Eat(); eat = EatFactory.CreateEatMethod("Fried"); eat.Eat(); } }

测试结果:

2.策略模式来设计

上面虽然用简单工厂实现了,但是感觉各种吃饺子的方式,用工厂来创建还是显得比较生硬,每一种吃法应该看成是一种算法,最终的目的都是吃掉,所以这里就引出了策略模式的概念了。

策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。

这个模式涉及到三个角色:

环境(Context)角色:持有一个Strategy类的引用。抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。

看了UML图感觉和简单工厂也没啥区别啊,不过是把Factory变成了Context而已,但是还是有些不同的,详见//www.jb51.net/article/254877.htm

这里和上面的简单工厂只有EatContext和客户端不一样

EatContext.cs

public class EatContext { private EatMethod _eat; public EatContext(EatMethod eat) { _eat = eat; } public void Eat() { _eat.Eat(); } }

Program.cs

EatContext ec = new EatContext(new Steamed()); ec.Eat(); ec = new EatContext(new Boiled()); ec.Eat(); ec = new EatContext(new Fried()); ec.Eat();

测试执行结果:

3.对比策略模式和简单工厂模式

我的理解是这样的:

首先是简单工厂模式:

客户端去调用工厂中的CreateEatMenthod方法,从输入上看,是一个字符串,指明了我想要的对象,然后工厂方法,就返回了一个我想要的对象,后面的具体的Eat(),是在客户端使用返回的对象进行调用的。

然后是策略模式:

客户端实例化一个EatContext对象,传入的参数是一个具体的怎么做饺子的对象,然后EatContext根据传入的对象,来初始化一个EatContext对象,后续的客户端操作通过的是EatContext的实例对象来完成的。

上面也能看出来,简单工厂用于创建对象,而策略模式更在乎控制行为,所以前者是创建型模式,后者是行为型模式。

实际应用中,可以将两者在进一步结合,再修改一下程序

EatFactoryContext.cs

public class EatFactoryContext { EatMethod _eat = null; public EatFactoryContext(string eatMethod) { switch (eatMethod) { case "Steamed": _eat = new Steamed(); break; case "Boiled": _eat = new Boiled(); break; case "Fried": _eat = new Fried(); break; default: break; } } public void Eat() { _eat.Eat(); } }

Program.cs

#region 结合 EatFactoryContext efc = new EatFactoryContext("Steamed"); efc.Eat(); efc = new EatFactoryContext("Boiled"); efc.Eat(); efc = new EatFactoryContext("Fried"); efc.Eat(); #endregion

测试结果:

4.总结

经过学习呢,发现是能够把简单工厂和策略模式进行基本的了解,但是如果工作中没有实际遇到,的确对于两者的区别的理解感到困惑,可能很多人和我一样,都是看到UML图发现,两者好像没有什么差别,可能理解还不深入吧,写得可能有些地方还不是很正确,希望看到的高手能指点一二。

到此这篇关于C#实现策略模式的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持易知道(ezd.cc)。

推荐阅读

    foreach的用法c语言和c#

    foreach的用法c语言和c#,数组,遍历,本文目录foreach的用法c语言和c#详细讲解foreach循环的用法C#中的foreach 怎么用啊foreach用法C#中的f

    params 是什么意思,c#里

    params 是什么意思,c#里,参数,数组,本文目录params 是什么意思,c#里params.add跟params.put有区别吗C#中ref,out和params有什么区别发送请

    C# 基于StackExchange.Redis.dll利用Redis实现分布式Session

    C# 基于StackExchange.Redis.dll利用Redis实现分布式Session,令牌,客户端,最近在研发一款O2O产品,考虑到分布式架构的需要,以前那一套.NET的

    c#中 (ToolStrip

    c#中 (ToolStrip,窗体,控件,本文目录c#中 (ToolStrip)控件是做什么用的winform窗体问题 toolstrip怎么重用,每个窗体都要用到同样的工具栏窗体

    C#取得DataTable最大值、最小值

    C#取得DataTable最大值、最小值,最大值,最小值,C#取得DataTable最大值、最小值int max=int.Parse((dtItemsAll.Compute("Max(CPITEMS_SOR

    C#如何打印|cctv5体育节目表

    C#如何打印|cctv5体育节目表,,C#如何打印最省事的办法,引用word对象,再把word弹出来用word打印,比较适合你这样刚学的,还不容易出错。cctv5体

    C#中的listview控件怎么用

    C#中的listview控件怎么用,控件,第一个,C#中的listview控件怎么用比如你在窗体上放了一个ListView,教你一些简单的操作。listView1.Columns