解释器模式(interpreter)
给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
解释:当某个程序要处理多种不同但是又有些类似的情形时,使用一种简单的语言来描述这些情形让程序来解释这种语言回事一种非常好的有效的方式。这有些类似宏定义,通过宏定义,然后后面的解释器解释这个宏的操作。也有点类似在SQL查询语句中的例子,通过输入一个查询语句,后台解释器对SQL语言进行解释,然后返回给用户不同形式的数据。
在很多场合都需要把数字转换成中文,我们就可以使用解释器来实现该功能,把给定的数字解释成符合语法规范的汉字表示法。实现代码如下:
// 抽象表达式
public abstract class Expression
{
protected Dictionary<string, int> table = new Dictionary<string, int>(9);
protected Expression()
{
table.Add("一", 1);
table.Add("二", 2);
table.Add("三", 3);
table.Add("四", 4);
table.Add("五", 5);
table.Add("六", 6);
table.Add("七", 7);
table.Add("八", 8);
table.Add("九", 9);
}
public virtual void Interpreter(Context context)
{
if (context.Statement.Length == 0)
{
return;
}
foreach (string key in table.Keys)
{
int value = table[key];
if (context.Statement.EndsWith(key + GetPostFix()))
{
context.Data += value * this.Multiplier();
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
}
if (context.Statement.EndsWith("零"))
{
context.Statement = context.Statement.Substring(0, context.Statement.Length - 1);
}
}
}
public abstract string GetPostFix();
public abstract int Multiplier();
//这个可以通用,但是对于个位数字例外,所以用虚方法
public virtual int GetLength()
{
return this.GetPostFix().Length + 1;
}
}
//个位表达式
public sealed class GeExpression : Expression
{
public override string GetPostFix()
{
return "";
}
public override int Multiplier()
{
return 1;
}
public override int GetLength()
{
return 1;
}
}
//十位表达式
public sealed class ShiExpression : Expression
{
public override string GetPostFix()
{
return "十";
}
public override int Multiplier()
{
return 10;
}
}
//百位表达式
public sealed class BaiExpression : Expression
{
public override string GetPostFix()
{
return "百";
}
public override int Multiplier()
{
return 100;
}
}
//千位表达式
public sealed class QianExpression : Expression
{
public override string GetPostFix()
{
return "千";
}
public override int Multiplier()
{
return 1000;
}
}
//万位表达式
public sealed class WanExpression : Expression
{
public override string GetPostFix()
{
return "万";
}
public override int Multiplier()
{
return 10000;
}
public override void Interpreter(Context context)
{
if (context.Statement.Length == 0)
{
return;
}
ArrayList tree = new ArrayList();
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpression());
tree.Add(new QianExpression());
foreach (string key in table.Keys)
{
if (context.Statement.EndsWith(GetPostFix()))
{
int temp = context.Data;
context.Data = 0;
context.Statement = context.Statement.Substring(0, context.Statement.Length - this.GetLength());
foreach (Expression exp in tree)
{
exp.Interpreter(context);
}
context.Data = temp + context.Data * this.Multiplier();
}
}
}
}
//环境上下文
public sealed class Context
{
private string _statement;
private int _data;
public Context(string statement)
{
this._statement = statement;
}
public string Statement
{
get { return this._statement; }
set { this._statement = value; }
}
public int Data
{
get { return this._data; }
set { this._data = value; }
}
}
//客户端
string roman = "七千三百零二万六千四百五十二";
//分解:((七千)(三百)(零)(二)万)
//((六千)(四百)(五十)(二))
Context context = new Context(roman);
ArrayList tree = new ArrayList();
tree.Add(new GeExpression());
tree.Add(new ShiExpression());
tree.Add(new BaiExpression());
tree.Add(new QianExpression());
tree.Add(new WanExpression());
foreach (Expression exp in tree)
{
exp.Interpreter(context);
}
Console.Write(context.Data);
Console.Read();
—————————————————————————————————————————————————————
中介者模式(Mediator)
用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使用其耦合松散,而且可以独立地改变他们之间的交互。
解释:从生活中的例子可以看出,不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中间平台与其他QQ用户进行交流,如果没有这些中间平台,我们如果想与朋友进行聊天的话,可能就需要当面才可以了。电话、短信也同样是一个中间平台,有了这个中间平台,每个用户都不要直接依赖与其他用户,只需要依赖这个中间平台就可以了,一切操作都由中间平台去分发。
//客户端
UnitedNationsSecurityCouncil UNSC = new UnitedNationsSecurityCouncil();
USA c1 = new USA(UNSC);
Iraq c2 = new Iraq(UNSC);
UNSC.Colleague1 = c1;
UNSC.Colleague2 = c2;
c1.Declare("不准研制核武器,否则要发动战争!");
c2.Declare("我们没有核武器,也不怕侵略。");
Console.Read();
//联合国机构 相当于Mediator类 抽象中介者
abstract class UnitedNations
{
//声明
public abstract void Declare(string message, Country colleague);
}
//联合国安全理事会 ConcreteMediator类 具体中介者
class UnitedNationsSecurityCouncil : UnitedNations
{
private USA colleague1;
private Iraq colleague2;
//美国
public USA Colleague1
{
set { colleague1 = value; }
}
//伊拉克
public Iraq Colleague2
{
set { colleague2 = value; }
}
//声明
public override void Declare(string message, Country colleague)
{
if (colleague == colleague1)
{
colleague2.GetMessage(message);
}
else
{
colleague1.GetMessage(message);
}
}
}
//国家类 相当于Colleague类 抽象同事类
abstract class Country
{
protected UnitedNations mediator;
public Country(UnitedNations mediator)
{
this.mediator = mediator;
}
}
//美国类 相当于ConcreteColleague1类 具体同事类
class USA : Country
{
public USA(UnitedNations mediator)
: base(mediator)
{ }
//声明
public void Declare(string message)
{
mediator.Declare(message, this);
}
//获得消息
public void GetMessage(string message)
{
Console.WriteLine("美国获得对方消息:" + message);
}
}
//伊拉克类 相当于ConcreteColleague2类
class Iraq : Country
{
public Iraq(UnitedNations mediator)
: base(mediator)
{ }
//声明
public void Declare(string message)
{
mediator.Declare(message, this);
}
//获得消息
public void GetMessage(string message)
{
Console.WriteLine("伊拉克获得对方消息:" + message);
}
}
—————————————————————————————————————————————————————
访问者模式(Visitor)
表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
解释:对象结构中对象对应的类很少改变,但经常需要在此对象结构上定义新的操作。需要对一个对象结构中的对象进行很多不同的并且不相关的操作,而需要避免让这些操作"污染"这些对象的类,也不希望在增加新操作时修改这些类。我们使用了一个访问者类,它改变了元素类的执行算法。通过这种方式,元素的执行算法可以随着访问者改变而改变。
//客户端吧
ObjectStructure o =new ObjectStructure();
o.Attach(new Man());
o.Attach(new Woman());
//成功时的反映
Success v1 = new Success();
o.Display(v1);
//失败时的反映
Failing v2 = new Failing();
o.Display(v2);
//恋爱时的反映
Amativeness v3 = new Amativeness();
o.Display(v3);
Console.Read();
//“状态”的抽象类
abstract class Action
{
//得到男人结论或反映
public abstract void GetManConclusion(Man concreteElementA);
//得到女人结论或反映
public abstract void GetWomanConclusion(Woman concreteElementB);
}
//具体“状态”类
//成功
class Success : Action
{
public override void GetManConclusion(Man concreteElementA)
{
Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人。", concreteElementA.GetType().Name,this.GetType().Name);
}
public override void GetWomanConclusion(Woman concreteElementB)
{
Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人。", concreteElementB.GetType().Name, this.GetType().Name);
}
}
//失败
class Failing : Action
{
public override void GetManConclusion(Man concreteElementA)
{
Console.WriteLine("{0}{1}时,闷头喝酒,谁也劝不动。", concreteElementA.GetType().Name,this.GetType().Name);
}
public override void GetWomanConclusion(Woman concreteElementB)
{
Console.WriteLine("{0}{1}时,眼泪汪汪,谁也劝不了。", concreteElementB.GetType().Name, this.GetType().Name);
}
}
//恋爱
class Amativeness : Action
{
public override void GetManConclusion(Man concreteElementA)
{
Console.WriteLine("{0}{1}时,凡事不懂也要装懂。", concreteElementA.GetType().Name, this.GetType().Name);
}
public override void GetWomanConclusion(Woman concreteElementB)
{
Console.WriteLine("{0}{1}时,遇事懂也装不懂。", concreteElementB.GetType().Name, this.GetType().Name);
}
}
//“人”的抽象类
abstract class Person
{
//接受
public abstract void Accept(Action visitor);
}
//具体 男人
class Man : Person
{
public override void Accept(Action visitor)
{
visitor.GetManConclusion(this);
}
}
//具体 女人
class Woman : Person
{
public override void Accept(Action visitor)
{
visitor.GetWomanConclusion(this);
}
}
//对象结构
class ObjectStructure
{
private IList<Person> elements = new List<Person>();
//增加
public void Attach(Person element)
{
elements.Add(element);
}
//移除
public void Detach(Person element)
{
elements.Remove(element);
}
//查看显示
public void Display(Action visitor)
{
foreach (Person e in elements)
{
e.Accept(visitor);
}
}
}
—————————————————————————————————————————————————————
策略模式(Strategy)
它定义了算法家族,分别分装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的用户。
解释:在现实生活中,策略模式的例子也非常常见,例如,中国的所得税,分为企业所得税、外商投资企业或外商企业所得税和个人所得税,针对于这3种所得税,针对每种,所计算的方式不同,个人所得税有个人所得税的计算方式,而企业所得税有其对应计算方式。
namespace _02商场收银软件
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//现金收费抽象类
abstract class CashSuper
{
public abstract double acceptCash(double money);
}
//正常收费子类
class CashNormal : CashSuper
{
public override double acceptCash(double money)
{
return money;
}
}
//打折收费子类
class CashRebate : CashSuper
{
private double moneyRebate = 1d;
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double acceptCash(double money)
{
return money * moneyRebate;
}
}
//返利收费子类
class CashReturn : CashSuper
{
private double moneyCondition = 0.0d;
private double moneyReturn = 0.0d;
public CashReturn(string moneyCondition, string moneyReturn)
{
this.moneyCondition = double.Parse(moneyCondition);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double acceptCash(double money)
{
double result=money;
if (money >= moneyCondition)
result = money - Math.Floor(money / moneyCondition) * moneyReturn;
return result;
}
}
//上下文
class CashContext
{
private CashSuper cs;
public CashContext(CashSuper csuper)
{
this.cs = csuper;
}
public double GetResult(double money)
{
return cs.acceptCash(money);
}
}
//客户端主要代码
private void Form1_Load(object sender, EventArgs e)
{
cbxType.Items.AddRange(new object[]{"正常收费","满300返100","打8折"});
cbxType.SelectedIndex=0;
}
double total = 0.0d;//用于总计
private void btnOK_Click(object sender, EventArgs e)
{
CashContext cc = null;
switch (cbxType.SelectedItem.ToString())
{
case "正常收费":
cc = new CashContext(new CashNormal());break;
case "满300返100":
cc = new CashContext(new CashReturn("300", "100"));break;
case "打8折":
cc = new CashContext(new CashRebate("0.8"));break;
}
double totalPrices = 0d;
totalPrices = cc.GetResult(Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));
total = total + totalPrices;
lbxList.Items.Add("单价:" + txtPrice.Text + "数量:" + txtNum.Text + " " + cbxType.SelectedItem + "合计:" + totalPrices.ToString());
lblResult.Text = total.ToString();
}
—————————————————————————————————————————————————————
备忘录模式(Memento)
在不破坏封装性的前提下,捕获一个对象的内部状态,并在给对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。
解释:从字面意思就可以明白,备忘录模式就是对某个类的状态进行保存下来,等到需要恢复的时候,可以从备忘录中进行恢复。生活中这样的例子经常看到,如备忘电话通讯录,备份操作操作系统,备份数据库等。
//客户端
//大战Boss前
GameRole lixiaoyao = new GameRole();
lixiaoyao.GetInitState();
lixiaoyao.StateDisplay();
//保存进度
RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
stateAdmin.Memento = lixiaoyao.SaveState();
//大战Boss时,损耗严重
lixiaoyao.Fight();
lixiaoyao.StateDisplay();
Console.Read();
//游戏角色
class GameRole
{
//生命力
private int vit;
public int Vitality
{
get { return vit; }
set { vit = value; }
}
//攻击力
private int atk;
public int Attack
{
get { return atk; }
set { atk = value; }
}
//防御力
private int def;
public int Defense
{
get { return def; }
set { def = value; }
}
//保存角色状态
public RoleStateMemento SaveState()
{
return (new RoleStateMemento(vit,atk,def));
}
//恢复角色状态
public void RecoveryState(RoleStateMemento memento)
{
this.vit = memento.Vitality;
this.atk = memento.Attack;
this.def = memento.Defense;
}
//状态显示
public void StateDisplay()
{
Console.WriteLine("角色当前状态:");
Console.WriteLine("体力:{0}", this.vit);
Console.WriteLine("攻击力:{0}", this.atk);
Console.WriteLine("防御力:{0}", this.def);
Console.WriteLine("");
}
//获得初始状态
public void GetInitState()
{
this.vit = 100;
this.atk = 100;
this.def = 100;
}
//战斗
public void Fight()
{
this.vit = 0;
this.atk = 0;
this.def = 0;
}
}
//角色状态存储箱
class RoleStateMemento
{
private int vit;
private int atk;
private int def;
public RoleStateMemento(int vit, int atk, int def)
{
this.vit = vit;
this.atk = atk;
this.def = def;
}
//生命力
public int Vitality
{
get { return vit; }
set { vit = value; }
}
//攻击力
public int Attack
{
get { return atk; }
set { atk = value; }
}
//防御力
public int Defense
{
get { return def; }
set { def = value; }
}
}
//角色状态管理者类
class RoleStateCaretaker
{
private RoleStateMemento memento;
public RoleStateMemento Memento
{
get { return memento; }
set { memento = value; }
}
}
}
—————————————————————————————————————————————————————
迭代器模式(Iterator)
提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。
解释:迭代器是针对集合对象而生的,对于集合对象而言,必然涉及到集合元素的添加删除操作,同时也肯定支持遍历集合元素的操作,我们此时可以把遍历操作也放在集合对象中,但这样的话,集合对象就承担太多的责任了,面向对象设计原则中有一条是单一职责原则,所以我们要尽可能地分离这些职责,用不同的类去承担不同的职责。迭代器模式就是用迭代器类来承担遍历集合元素的职责。
//客户端
ConcreteAggregate a = new ConcreteAggregate();
a[0] = "大鸟";
a[1] = "小菜";
a[2] = "行李";
a[3] = "老外";
a[4] = "公交内部人员";
a[5] = "小偷";
Iterator i = new ConcreteIterator(a);
//Iterator i = new ConcreteIteratorDesc(a);
object item = i.First();
while (!i.IsDone())
{
Console.WriteLine("{0}请买车票!", i.CurrentItem());
i.Next();
}
Console.Read();
//Iterator迭代器抽象类
abstract class Iterator
{
public abstract object First();
public abstract object Next();
public abstract bool IsDone();
public abstract object CurrentItem();
}
//Aggregate聚集抽象类
abstract class Aggregate
{
public abstract Iterator CreateIterator();
}
//ConcreteIterator具体迭代器类,继承Iterator
class ConcreteIterator : Iterator
{
private ConcreteAggregate aggregate;
private int current=0;
public ConcreteIterator(ConcreteAggregate aggregate)
{
this.aggregate=aggregate;
}
public override object First()
{
return aggregate[0];
}
public override object Next()
{
object ret=null;
current ++;
if(current<aggregate.Count)
{
ret=aggregate[current];
}
return ret;
}
public override bool IsDone()
{
return current>=aggregate.Count?true :false;
}
public override object CurrentItem()
{
return aggregate[current];
}
}
//ConcreteAggregate具体聚集类 继承Aggregate
class ConcreteAggregate:Aggregate
{
private IList<object> items=new List<object>();
public override Iterator CreateIterator()
{
return new ConcreteIterator (this);
}
public int Count
{
get{return items.Count;}
}
public object this[int index]
{
get{return items[index];}
set{items.Insert(index,value);}
}
}
}