23种设计模式【C#代码举例】(下)

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 23种设计模式【C#代码举例】

23种设计模式【C#代码举例】(上):https://developer.aliyun.com/article/1556288

第十五章 抽象工厂模式 167

提供一个创建一系列相关或者额相互依赖的对象的接口,而无需指定它们的具体的类;

//数据实体
    public class DataUser
    {
        public DataUser(string name,string id)
        {
            Name = name;Id = id;
        }
        public string Name { get; set; }
        public string Id { get; set; }
    }
    public class DataDepartment
    {
        public DataDepartment(string deptname, string id)
        {
            Deptname = deptname;
            Id = id;
        }
        public string Deptname { get; set; }
        public string Id { get; set; }
    }
    //User操作接口
    public interface IUser
    {
        public void Insert(DataUser u);
        public DataUser Get();
    }
    //User操作具体类
    public class SqlserverUser : IUser
    {
        public DataUser Get()
        {
            Console.WriteLine("Sqlserver获取用户");
            return null;
        }
        public void Insert(DataUser u)
        {
            Console.WriteLine("Sqlserver添加用户");
            
        }
    }
    public class AccessUser : IUser
    {
        public DataUser Get()
        {
            Console.WriteLine("Access获取用户");
            return null;
        }
        public void Insert(DataUser u)
        {
            Console.WriteLine("Access添加用户");
        }
    }
    //Department操作接口
    public interface IDepartment
    {
        public void Insert(DataDepartment d);
        public DataDepartment Get();
    }
    //Department操作具体类
    public class SqlserverDepartment : IDepartment
    {
        public DataDepartment Get()
        {
            Console.WriteLine("Sqlserver获取部门");
            return null;
        }
        public void Insert(DataDepartment d)
        {
            Console.WriteLine("Sqlserver添加部门");
        }
    }
    public class AccessDepartment : IDepartment
    {
        public DataDepartment Get()
        {
            Console.WriteLine("Access获取部门");
            return null;
        }
        public void Insert(DataDepartment d)
        {
            Console.WriteLine("Access添加部门");
        }
    }
    //操作类工厂接口
    public interface IFactory
    {
        public IUser CreateUser();
        public IDepartment CreateDepartment();  
    }
    //操作类工厂的具体实现类
    class SqlserverFactory : IFactory
    {
        public IDepartment CreateDepartment()
        {
            return new SqlserverDepartment();
        }
        public IUser CreateUser()
        {
            return new SqlserverUser(); ;
        }
    }
    class AccessFactory : IFactory
    {
        public IDepartment CreateDepartment()
        {
            return new AccessDepartment();
        }
        public IUser CreateUser()
        {
            return new AccessUser(); ;
        }
}
--测试:换了工厂类factory,数据库访问则被更换;
DataUser user=new DataUser("张三","U01");
DataDepartment dept = new DataDepartment("财务部","D001");
//IFactory factory = new AccessFactory();
IFactory factory = new SqlserverFactory();
IUser iu= factory.CreateUser();
IDepartment idept= factory.CreateDepartment();
iu.Insert(user);
iu.Get();
idept.Insert(dept);
idept.Get();

缺点:增加一个表project;需要增加DataProject数据类。还需要增加三个操作类IProject,SQLserverProject,AccessProject,修改三个类,IFactory,SQLserverFactory,AccessFactory。

更换数据库是方便,但是实现过程,每增加一个表,要增加或更改的地方太多了。

关于抽象工厂的优化:用简单工厂完成factory的部分;一个DataAccess工具类足矣(不同数据库的相应表的操作类实例化);略;

对抽象工厂优秀的优化方案:反射+抽象工厂

Assembly.Load(“程序集名称”).CreateInstance(命名空间.类名称);

常规活的实例的方法

IUser iu=new SqlserverUser();

反射获取实例方法

IUser iu=(IUser)Assembly.Load(“AbsFactory”).CreateInstance(“AbsFactory.Sqlserver”);

实现后的DataAccess如下;

class DataAccess
    {
        private static readonly string AssemblyName = "AbsFactory";
        private static readonly string db = "sqlserver";
        public static IUser CreateUser()
        {
            string classname = AssemblyName + "." + db + "User";
            return (IUser)Assembly.Load(AssemblyName).CreateInstance(classname);
        }
        public static IDepartment CreateDepartment()
        {
            string classname = AssemblyName + "." + db + "Department";
            return (IDepartment)Assembly.Load(AssemblyName).CreateInstance(classname);
        }
}

如果增加了一个表Project。则DataAccess增加一个CreateProject方法;增加三个Project相关类;

更优化的方法:

将数据库字符串放在配置文件中。这样改变数据库,只需要改变配置文件,而不需要重新编译程序;这样会少了一些关于数据库选择Switch语句;

第十六章 状态模式

当一个对象状态改变时,允许改变起行为,这个对象看起来像是改变了其类;

优点:将于特定状态相关的行为局部化,并且将不同状态的行为分割开来;

使用时机:一个对象的行为取决于他的状态,并且它必须在运行时时刻根据状态改变行为,此时可以考虑使用状态模式。

每个状态对应一个状态类,改变状态就是改变了状态类。

public class Work
    {
        public double Hour { get; set; }
        public bool Finish { get; set; }
        public State State { get; set; }
        public Work()
        {
            State=new ForenoonState();
        }
        public void SetState(State s)
        {
            State = s;
        }
        public void WriteProgram()
        {
            State.WriteProgram(this);
        }
    }
    //抽象状态类
    public abstract class State
    {
        public abstract void WriteProgram(Work w);
    }
    //具体状态:上午
    public class ForenoonState : State
    {
        public override void WriteProgram(Work w)
        {
            if (w.Hour < 12)
            {
                Console.WriteLine("当前时间:{0}点,上午工作,精神百倍。",w.Hour);
            }
            else
            {
                w.SetState(new NoonState());
                w.WriteProgram();
            }
        }
    }
    //具体状态:中午
    public class NoonState : State
    {
        public override void WriteProgram(Work w)
        {
            if (w.Hour >=12&&w.Hour<=13)
            {
                Console.WriteLine("当前时间:{0}点,中午工作,精神不太好。", w.Hour);
            }
            else
            {
                w.SetState(new AfternoonState());
                w.WriteProgram();
            }
        }
    }
    //具体状态:下午
    public class AfternoonState : State
    {
        public override void WriteProgram(Work w)
        {
            if (w.Hour > 13)
            {
                Console.WriteLine("当前时间:{0}点,上午工作,精神还可以。", w.Hour);
            }
            else
            {
                w.SetState(new ForenoonState());
                w.WriteProgram();
            }
        }
}
--代码测试
//状态模式
Work w = new Work();
w.Hour = 9;
w.WriteProgram();
w.Hour = 10;
w.WriteProgram();
w.Hour = 11;
w.WriteProgram();
w.Hour = 12;
w.WriteProgram();
w.Hour = 13;
w.WriteProgram();
w.Hour = 14;
w.WriteProgram();
w.Hour = 15;
w.WriteProgram();
w.Hour = 16;
w.WriteProgram();

第十七章 适配器模式 197

将一个类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作的类可以一起工作。

适配器分类:

类适配器:通过多重继承对一个接口与另一个接口进行匹配。很多语言不支持多重继承。

对象适配器:主要的适配器类别。

使用时机:两个类所做事情相同或类似,单具有的接口不同;而双方都不易修改;

//目标,客户需求接口
    public class Target
    {
        public virtual void Request()
        {
            Console.WriteLine("普通请求!");
        }
    }
    //需要适配的类
    class Adaptee
    {
        public virtual void SpecificRequest()
        {
            Console.WriteLine("特殊请求!");
        }
    }
    //适配器,通过内部包装一个需要适配的类,把源接口转换成目标接口
    class Adapter :Target {
        private Adaptee adaptee = new Adaptee();
        public override void Request()
        {
            adaptee.SpecificRequest();
        }
}
//测试代码
Target target = new Adapter();
target.Request();

第十八章 备忘录模式 206

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以讲该对象恢复到原先保存的状态。

我首先想到的就是单机游戏的存档。

发起人:创建备忘录memento;

备忘录memento:存储对象状态;

管理者:保存备忘录;

场合:功能复杂,需要维护或记录属性历史的类,或者需要保存属性只是众多属性中一部分。可以更具备忘录保存的信息还原到前一状态。

//发起人
    public class Originator
    {
        public string State { get; set; }
        public Memento CreateMemento()
        {
            return new Memento(State);
        }
        public void SetMemento(Memento memento)
        {
            State = memento.State;
        }
        public void Show()
        {
            Console.WriteLine("State={0}",State);
        }
    }
    //备忘录
    public class Memento
    {
        public String State { get; set; }
        public Memento(string state)
        {
            State = state;
        }
    }
    //管理者
    public class Caretaker
    {
        public Memento memento { get; set; }
}
//测试代码
Originator o = new Originator();
o.State = "On";
o.Show();
Caretaker caretaker = new Caretaker();
caretaker.memento = o.CreateMemento();
o.State = "Off";
o.Show();
o.SetMemento(caretaker.memento);
o.Show();

第十九章 组合模式 215

将对象组合成树形结构以表示部分和整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性;

使用的时机:需求是提现部分与整体的层次结构,并忽略组合对象与单个对象的不同,统一使用组合结构中的所有对象时,考虑使用组合模式;

abstract class Componet
    {
        protected Componet(string name)
        {
            Name = name;
        }
        public abstract string Name { get; set; }
        public abstract void Add(Componet c);
        public abstract void Remove(Componet c);
        public abstract void Display(int depth);
    }
    class Leaf : Componet
    {
        public Leaf(string name):base(name)
        {
        }
        public override string Name { get; set; }
        public override void Add(Componet c)
        {
            Console.WriteLine("Can't add to a leaf");
        }
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-',depth)+Name);
        }
        public override void Remove(Componet c)
        {
            Console.WriteLine("Can't remove from a leaf");
        }
    }
    class Composite : Componet
    {
        public List<Componet> children { get; set; }= new List<Componet>();
        public Composite(string name) : base(name)
        {
        }
        public override string Name { get; set; }
        public override void Add(Componet c)
        {
            children.Add(c);
        }
        public override void Display(int depth)
        {
            Console.WriteLine(new String('-', depth) + Name);
            foreach(var c in children)
            {
                c.Display(depth + 2);
            }
        }
        public override void Remove(Componet c)
        {
            children.Remove(c);
        }
}
//测试代码
Composite root = new Composite("root");
root.Add(new Leaf("Leaf A"));
root.Add(new Leaf("Leaf B"));
Composite comp = new Composite("composite X");
comp.Add(new Leaf("Leaf XA"));
comp.Add(new Leaf("Leaf XB"));
root.Add(comp);
Composite comp1 = new Composite("composite XY");
comp1.Add(new Leaf("Leaf XYA"));
comp1.Add(new Leaf("Leaf XYB"));
root.Add(comp1);
root.Display(0);

第二十章 迭代模式

提供一种方法,顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示。

//迭代器抽象类
    abstract class Iterator
    {
        public abstract object First();
        public abstract object Next();
        public abstract bool IsDone();
        public abstract object CurrentItem();
    }
    //聚集抽象类
    abstract class Aggregate
    {
        public abstract Iterator CreaeteIterator();
    }
    //具体迭代类,继承抽象迭代器
    class ConcreteIterator : Iterator
    {
        private ConcreteAggregate aggregate;
        private int current=0;
        public ConcreteIterator(ConcreteAggregate aggregate)
        {
            this.aggregate = aggregate;
        }
        public override object CurrentItem()
        {
           return aggregate[current];
        }
        public override object First()
        {
            return aggregate[0];
        }
        public override bool IsDone()
        {
            return current>=aggregate.Count;
        }
        public override object Next()
        {
            object ret = null;
            current ++;
            if (current < aggregate.Count)
            {
                ret= aggregate[current];
            }
            return ret;
        }
    }
    //具体聚集类,继承Aggieregate
    class ConcreteAggregate : Aggregate
    {
        private IList<Object> items = new List<Object>();
        public int Count { get { return items.Count; } }
        public Object this[int index] { 
            get { return items[index]; } 
            set { items.Insert(index, value); } 
        }
        public override Iterator CreaeteIterator()
        {
            throw new NotImplementedException();
        }
}
//代码测试
ConcreteAggregate a = new ConcreteAggregate();
a[0] = "大鸟0";
a[1] = "大鸟1";
a[2] = "大鸟2";
a[3] = "大鸟3";
a[4] = "大鸟4";
Iterator i = new ConcreteIterator(a);
object item = i.First();
while (!i.IsDone())
{
    Console.WriteLine("买票:{0}",i.CurrentItem());
    i.Next();
}

现在泛滥的for应用,使得迭代模式在很多集合中已经实现。所以自定义的迭代模式极少。甚至有人呼吁取消迭代模式;

第二十一章 单例模式 236

保证一个类只有一个实例,并提供一个访问它的全局访问点。

//多线程时的单例
    public class Singleton
    {
        private static Singleton? instance;
        private readonly static object syncRoot=new object();
        private Singleton()
        {
        }
        public static Singleton GetInstance()
        {
            //双重锁,去掉外层if也可以,就变成了单层锁
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            
            return instance;
        }
}

静态初始化

//静态初始化,要点就是sealed(阻止派生)和readonly(一次创建)
    public sealed  class Singleton
    {
        private static readonly Singleton instance = new Singleton();
        private Singleton() { }
        public static Singleton GetInstance()
        {
            return instance;
        }
    }

第二十二章 桥接模式 247

桥接模式:将抽象部分与它的实现部分分离,使他们都可以独立变化;

//手机软件,抽象类
   public abstract class HandsetSoft
    {
        public abstract void Run();
    }
    //手机软件,具体类
    public class HandsetGame : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("运行手机游戏");
        }
    }
    public class HandsetAddressList : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("运行手机通讯录");
        }
    }
    //手机品牌抽象类
    abstract class HandsetBrand
    {
        public HandsetSoft soft { get; set; }
        public abstract void Run();
    }
    //具体的手机品牌M,N
    class HandSetBrandM : HandsetBrand
    {
        public override void Run()
        {
            soft.Run();
        }
    }
    class HandSetBrandN : HandsetBrand
    {
        public override void Run()
        {
            soft.Run();
        }
}

测试代码

HandsetBrand ab = new HandSetBrandN();
ab.soft = new HandsetGame();
ab.Run();
ab.soft= new HandsetAddressList();
ab.Run();
ab = new HandSetBrandM();
ab.soft = new HandsetGame();
ab.Run();
ab.soft = new HandsetAddressList();
ab.Run();

如果新增了Mp3,则只需要新增一个类

public class HandsetMp3 : HandsetSoft
    {
        public override void Run()
        {
            Console.WriteLine("运行手机Mp3");
        }
    }

第二十三章 命令模式 261

将一个请求封装为一个对象,从而使你可用不同的请求对客户参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

//接受者:烤串的人;
    class Receiver
    {
        public void Action()
        {
            Console.WriteLine("执行请求");
        }
    }
    //抽象命令
    abstract class Command
    {
        public Receiver receiver { get; set; }
        public Command(Receiver receiver)
        {
            this.receiver = receiver;
        }   
        abstract public void Execute();
    }
    //具体命令
    class ConcreteCommand : Command
    {
        public ConcreteCommand(Receiver receiver) : base(receiver)
        {
        }
        public override void Execute()
        {
            receiver.Action();
        }
    }
    //要求该命令执行这个请求  :服务员
    class Invoker
    {
        public Command command { get; set; }
        public void ExecuteCommand()
        {
            command.Execute();
        }
}

执行代码 客户

Receiver r = new Receiver();
Command c = new ConcreteCommand(r);
Invoker i = new Invoker();
i.command=c;
i.ExecuteCommand();

整个过程就是:客户喊了个服务员,制定了一个命令。服务员带着命令,让执行者执行命令;

第二十四章 责任链模式

使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的偶合。将这个对象连成一个链,并沿着这条链传递改请求,直到有一个对象处理它 。

//申请
    class Request
    {
        public string requestType { get; set; }
        public string requestContent { get; set; }
        public int requestNumber { get; set; }
        public Request(string requestType, string requestContent, int requestNumber)
        {
            this.requestType = requestType;
            this.requestContent = requestContent;
            this.requestNumber = requestNumber;
        }
    }
    //管理者
    abstract class Manager
    {
        public  string Name { get; set; }
        //上级
        public  Manager superior { get; set; }
        protected Manager(string name)
        {
            Name = name;
        }
        protected Manager(Manager superior)
        {
            this.superior = superior;
        }
        abstract public void RequestApplications(Request request);
    }
    //经理
    class CommonManager : Manager
    {
        public CommonManager(string name) : base(name)
        {
        }
        public override void RequestApplications(Request request)
        {
            if (request.requestType == "请假" && request.requestNumber <= 2)
            {
                Console.WriteLine( "{0}:{1}{2}天被批准!",Name,request.requestContent,request.requestNumber);
            }
            else
            {
                if (superior != null)
                {
                    superior.RequestApplications(request);
                }
            }
        }
    }
    //总监
    class MajorManager : Manager
    {
        public MajorManager(string name) : base(name)
        {
        }
        public override void RequestApplications(Request request)
        {
            if (request.requestType == "请假" && request.requestNumber <= 5)
            {
                Console.WriteLine("{0}:{1}{2}天被批准!", Name, request.requestContent, request.requestNumber);
            }
            else
            {
                if (superior != null)
                {
                    superior.RequestApplications(request);
                }
            }
        }
    }
    //总经理
    class BossManager : Manager
    {
        public BossManager(string name) : base(name)
        {
        }
        public override void RequestApplications(Request request)
        {
            if (request.requestType == "请假")
            {
                Console.WriteLine("{0}:{1}{2}天被批准或者拒绝!", Name, request.requestContent, request.requestNumber);
            }
            else if (request.requestType == "加薪")
            {
                Console.WriteLine("{0}:{1}数量{2}被批准或者拒绝!", Name, request.requestContent, request.requestNumber);
            }
           
        }
}
//测试代码
CommonManager jinli = new CommonManager("锦鲤经理");
MajorManager major = new MajorManager("卡卡总监");
BossManager boss = new BossManager("博士老总");
jinli.superior = major;
major.superior = boss;
Request request = new Request("请假","小菜请假",3);
jinli.RequestApplications(request);

上面的管理者只列出了上级;

关于请求的发起来源及提交下级的情况应该怎么记录,做出思考;发起来源可以放在请求里;提交来源可以放在请求里,流程经手人都可以放在请求里按顺序存放。

第二十五章 中介者模式

中介者,也叫调停者。

中介者模式:用一个中介对象封装一些列的对象交互。中介者使各对象不要显式地相互作用,从而使其耦合松散,而且可以独立改变他们之间的交互。

//抽象中介者:联合国机构
    abstract class UnitedNations
    {
        //声明
        public abstract void Declare(string message,Country colleague);
    }
    //具体的中介 安理会
    class UnitedNationsSecurityCouncil : UnitedNations
    {
        public USA c1;
        public Iraq c2;
        public override void Declare(string message, Country colleague)
        {
            if (colleague == c1)
            {
                c2.GetMessage(message);
            }
            else if(colleague == c2)
            {
                c1.GetMessage(message);
            }
        }
    }
    //需要被中介的抽象类:国家
    abstract class Country
    {
       
        public UnitedNations mediator { get; }
        protected Country(UnitedNations mediator)
        {
            this.mediator = mediator;
        }
       
    }
    //具体的国家类
    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("USA获得消息:"+message);
        }
    }
    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);
        }
}
//测试代码
UnitedNationsSecurityCouncil uni = new UnitedNationsSecurityCouncil();
USA usa = new USA(uni);
Iraq iraq = new Iraq(uni);
uni.c1=usa;
uni.c2=iraq;
usa.Declare("美国声明:我要打你了");
iraq.Declare("伊拉克声明:你可以试试");

最简单的就是1对1的中介模式;也可以是1对多模式;多对多模式我暂时没想出来;但是只要制定了规则,多对多按规则交互也是可以的。就是按规则在中间类内部进行了信息的交流。

第二十六章 享元模式

享元模式:运用共享技术有效支持大量细粒度的对象。

//用户
    public class User
    {
        public string Name { get; set; }
        public User(string name)
        {
            Name = name;
        }
    }
    //抽象网站
    abstract class WebSite
    {
        public abstract void Use(User user);
    }
    //实际网站
    class ConcreteWebSite : WebSite
    {
        public string Name { get; set; }
        public ConcreteWebSite(string name)
        {
            Name = name;
        }
        public override void Use(User user)
        {
            Console.WriteLine("网站分类:{0} ;用户:{1}",Name ,user.Name);
        }
    }
    //网站工厂
    class WebSiteFactory
    {
        public Hashtable flyweights = new Hashtable();
        //获得网站分类
        public WebSite GetWebSiteCategory(string key)
        {
            if (!flyweights.ContainsKey(key))
            {
                flyweights.Add(key, new ConcreteWebSite(key));
            }
            return (WebSite)flyweights[key];
        }
        //获取网站个数
        public int GetWebSiteCount()
        {
            return flyweights.Count;
        }
}
//测试代码
WebSiteFactory factory = new WebSiteFactory();
WebSite w1= factory.GetWebSiteCategory("展品展示");
w1.Use(new User("小菜2"));
WebSite w2 = factory.GetWebSiteCategory("展品展示");
w1.Use(new User("小菜1"));
WebSite w3 = factory.GetWebSiteCategory("展品展示");
w1.Use(new User("小菜3"));
WebSite w4 = factory.GetWebSiteCategory("博客");
w1.Use(new User("小菜4"));
WebSite w5 = factory.GetWebSiteCategory("博客");
w1.Use(new User("小菜5"));
WebSite w6 = factory.GetWebSiteCategory("博客");
w1.Use(new User("小菜2"));
Console.WriteLine("网站分类总数:{0}",factory.GetWebSiteCount());

分类不同才是真的不同。账号不同就是根据账号区分一下数据。

第二十七章 解释器模式

解释器模式:给定一个语言,定义他的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

时机:一种特定类型的问题发生频率足够高,那么可能就值得将该问题各个实例表述为一个简单语言中的句子。这样就可以构成一个解释器,该解释器通过解释这些句子来解决该问题。

举例:正则表达式;

class Context
    {
        public Context(string input)
        {
            Input = input;
        }
        public string Input { get; set; }
        public string Output { get; set; }
    }
    //抽象表达式
    abstract class AbstractExpression
    {
        //解释器
        public abstract void Interpret(Context context);
       
        //执行:如有必要,可以有多个执行;
        public abstract void Excute(string key, string value);
    }
    //A解释器
    class AExpression : AbstractExpression
    {
        public override void Excute(string key, string value)
        {
            if (key == "A")
            {
                Console.WriteLine("A终端解释器:{0}-{1}", key, value);
            }
        }
        public override void Interpret(Context context)
        {
            {
                Dictionary<string, string> dict = new Dictionary<string, string>();
                for (int i = 0; i < context.Input.Length / 2; i++)
                {
                    string key = context.Input.Substring(2 * i, 1);
                    string value = context.Input.Substring(2 * i + 1, 1);
                    Excute(key, value);
                }
            }
        }
    }
    //B解释器
    class BExpression : AbstractExpression
    {
        public override void Excute(string key, string value)
        {
            if (key == "B")
            {
                Console.WriteLine("A终端解释器:{0}-{1}", key, value);
            }
        }
        public override void Interpret(Context context)
        {
            {
                Dictionary<string, string> dict = new Dictionary<string, string>();
                for (int i = 0; i < context.Input.Length / 2; i++)
                {
                    string key = context.Input.Substring(2 * i, 1);
                    string value = context.Input.Substring(2 * i + 1, 1);
                    Excute(key, value);
                }
            }
        }
}
//执行代码
Context context = new Context("A0B2C3A4B5A6B8B9A0AaBb");
AbstractExpression expression=new BExpression();
expression.Interpret(context);
Console.ReadLine();

解释器,文法规则的设计很重要。

第二十八章 访问者模式

表示一个作用于某对象结构中的各元素操作。他使你可以在不改变各元素类的前提下定义作用于这些元素的新操作。

//抽象被访问者
   public abstract class Person
    {
        public abstract void Accept(Action visitor);
    }
    public class Man : Person
    {
        public override void Accept(Action visitor)
        {
           
            visitor.VisitMan(this);
        }
    }
    public class WoMan : Person
    {
        public override void Accept(Action visitor)
        {
            visitor.VisitWoMan(this);
        }
    }
    //抽象提问
    public abstract class Action
    {
        public abstract void VisitMan(Man man);
        public abstract void VisitWoMan(WoMan woman);
    }
    //成功
    class Success : Action
    {
        public override void VisitMan(Man man)
        {
            Console.WriteLine("{0}{1}时,背后多半有一个伟大的女人!",man.GetType().Name,this.GetType().Name);
        }
        public override void VisitWoMan(WoMan woman)
        {
            Console.WriteLine("{0}{1}时,背后多半有一个失败的男人!", woman.GetType().Name, this.GetType().Name);
        }
    }
    //结婚
    class Merry : Action
    {
        public override void VisitMan(Man man)
        {
            Console.WriteLine("{0}{1}时,【有妻徒刑】开始执行!", man.GetType().Name, this.GetType().Name);
        }
        public override void VisitWoMan(WoMan woman)
        {
            Console.WriteLine("{0}{1}时,【爱情保险】开始生效!", woman.GetType().Name, this.GetType().Name);
        }
}
//测试代码
List<Console23Style.HK.Visitor.Person> ps = new List<Console23Style.HK.Visitor.Person>();
ps.Add(new Man());
ps.Add(new WoMan());
Success success = new Success();
Merry merry = new Merry();
foreach (Console23Style.HK.Visitor.Person p in ps)
{
    p.Accept(success);
    p.Accept(merry);
}

多一个话题,既需要多一个action的子类;对Person和其子类没有影响;

关注我,不迷路,共学习,同进步

关注我,不迷路,同学习,同进步

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS&nbsp;SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/sqlserver
相关文章
|
1月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。
|
27天前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性和扩展性
【10月更文挑战第13天】 本文将探讨PHP中常见的设计模式及其在实际项目中的应用。通过对比传统编程方式,我们将展示设计模式如何有效地提高代码的可维护性和扩展性。无论是单例模式确保类的单一实例,还是观察者模式实现对象间的松耦合,每一种设计模式都为开发者提供了解决特定问题的最佳实践。阅读本文后,读者将能更好地理解和应用这些设计模式,从而提升PHP编程的效率和质量。
|
29天前
|
设计模式 安全 Java
C# 一分钟浅谈:设计模式之单例模式
【10月更文挑战第9天】单例模式是软件开发中最常用的设计模式之一,旨在确保一个类只有一个实例,并提供一个全局访问点。本文介绍了单例模式的基本概念、实现方式(包括饿汉式、懒汉式和使用 `Lazy&lt;T&gt;` 的方法)、常见问题(如多线程和序列化问题)及其解决方案,并通过代码示例详细说明了这些内容。希望本文能帮助你在实际开发中更好地应用单例模式,提高代码质量和可维护性。
29 1
|
1月前
|
C#
C# 图形验证码实现登录校验代码
C# 图形验证码实现登录校验代码
75 2
|
1月前
|
设计模式 SQL 安全
PHP中的设计模式:单例模式的深入探索与实践在PHP开发领域,设计模式是解决常见问题的高效方案集合。它们不是具体的代码,而是一种编码和设计经验的总结。单例模式作为设计模式中的一种,确保了一个类仅有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的基本概念、实现方式及其在PHP中的应用。
单例模式在PHP中的应用广泛,尤其在处理数据库连接、日志记录等场景时,能显著提高资源利用率和执行效率。本文从单例模式的定义出发,详细解释了其在PHP中的不同实现方法,并探讨了使用单例模式的优势与注意事项。通过对示例代码的分析,读者将能够理解如何在PHP项目中有效应用单例模式。
|
2月前
|
设计模式 算法 数据库连接
PHP中的设计模式:提高代码的可维护性与扩展性
设计模式在PHP开发中至关重要,如单例模式确保类仅有一个实例并提供全局访问点,适用于管理数据库连接或日志记录。工厂模式封装对象创建过程,降低系统耦合度;策略模式定义算法系列并使其可互换,便于实现不同算法间的切换。合理选择设计模式需基于需求分析,考虑系统架构,并通过测试驱动开发验证有效性,确保团队协作一致性和代码持续优化。设计模式能显著提升代码质量,解决开发中的设计难题。
33 8
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:提升代码的灵活性与可维护性
在本文中,我们将深入探讨PHP编程语言中的一种重要概念——设计模式。设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它代表了最佳的实践,被有经验的面向对象的软件开发人员所采用。本文将通过具体的实例,展示如何在PHP项目中应用设计模式,以提高代码的灵活性和可维护性。无论你是PHP初学者还是经验丰富的开发者,都能从中获得有价值的见解。
|
2月前
|
设计模式 算法 PHP
PHP中的设计模式:策略模式的深入探索与实践在软件开发的广袤天地中,PHP以其独特的魅力和强大的功能,成为无数开发者手中的得力工具。而在这条充满挑战与机遇的征途上,设计模式犹如一盏明灯,指引着我们穿越代码的迷雾,编写出更加高效、灵活且易于维护的程序。今天,就让我们聚焦于设计模式中的璀璨明珠——策略模式,深入探讨其在PHP中的实现方法及其实际应用价值。
策略模式,这一设计模式的核心在于它为软件设计带来了一种全新的视角和方法。它允许我们在运行时根据不同情况选择最适合的解决方案,从而极大地提高了程序的灵活性和可扩展性。在PHP这门广泛应用的编程语言中,策略模式同样大放异彩,为开发者们提供了丰富的创作空间。本文将从策略模式的基本概念入手,逐步深入到PHP中的实现细节,并通过一个具体的实例来展示其在实际项目中的应用效果。我们还将探讨策略模式的优势以及在实际应用中可能遇到的挑战和解决方案,为PHP开发者提供一份宝贵的参考。
|
2月前
|
设计模式 存储 数据库连接
探索PHP中的设计模式:提高代码的可维护性与扩展性
本文将深入探讨PHP中常用的设计模式,包括单例模式、工厂模式和观察者模式。通过具体的代码示例,展示如何在实际项目中应用这些设计模式,以提高代码的可维护性与扩展性。无论你是PHP初学者还是有一定经验的开发者,都可以通过本文的学习,提升你的编程技巧和项目架构能力。