首页 > 学院 > 开发设计 > 正文

【状态模式】 State Pattern

2019-11-17 02:53:08
字体:
来源:转载
供稿:网友

【状态模式】 State Pattern

我们先设计一个场景,饮料自动售卖机,来设计一下它的出售流程。

流程图中,我们可把这个过程看成几个状态: 投币状态,选择饮料状态,售出状态,出售完毕状态.

,有了这个四个状态,我们设计一下界面(很粗略):

在这里我们只定义了三种饮料和一个投币口,在设计接口和类之前,我们来看一下状态模式的UML图:

State接口定义了一个所有具体状态的共同接口;任何状态都实现这个相同的接口,这样一来,状态之间可以互相代替.

ConcreteState(具体状态)处理来自Context请求。每一个ConcreteState都提供了它自己对于请求的实现。所以,当Context改变状态时行为也跟着改变。

Context(上下文)是一个类,它可以拥有一些内部状态。

根据成熟的状态模式UML图,我们来设计我们自己的UML类图:

直接上代码(可能和UML图有些出入,多了些参数,图主要是搭出一个架构来)

实体类:

  public class SoftDrink    {        public string Name { get; set; }        public int PRice { get; set; }        public int Count { get; set; }        private SoftdrinkMachineContext _context = new SoftdrinkMachineContext();        public SoftdrinkMachineContext Context        {            get { return _context; }        }    }
View Code

创建获取某种饮料的工厂:

 public class SoftDrinkFactory    {        public static SoftDrink GetSoftDrink(string softDrinkName)        {            SoftDrink softDrink = SoftDrinkRepository.SoftDrinks.SingleOrDefault(s => s.Name.Equals(softDrinkName));            if (softDrink == null)                throw new ArgumentException(string.Format("没有该饮料:{0}", softDrinkName));            return softDrink;        }    }
View Code

饮料的存储库

 public class SoftDrinkRepository    {              static SoftDrinkRepository()        {            SoftDrinks = new List<SoftDrink>();            AddSoftDrink(new SoftDrink { Name = "可乐", Count = 5, Price = 3 });            AddSoftDrink(new SoftDrink { Name = "果粒橙", Count = 1, Price = 3 });            AddSoftDrink(new SoftDrink { Name = "咖啡", Count = 5, Price = 3 });        }        public static List<SoftDrink> SoftDrinks { get; private set; }        public static void AddSoftDrink(SoftDrink softDrink)        {            if (SoftDrinks.Any(s => s.Name.Equals(softDrink.Name)))            {                SoftDrink needtobeAddedSoftdrink = SoftDrinks.Single(s => s.Name.Equals(softDrink.Name));                needtobeAddedSoftdrink.Price = softDrink.Price;                needtobeAddedSoftdrink.Count = softDrink.Count;            }            SoftDrinks.Add(softDrink);        }    }
View Code

这里存钱的地方,相当于一个银行,用的是静态

  public class Constants    {        public static int StoredMoney { get; set; }    }
View Code

接口:

 public interface ISoftdrinkState    {        void InsertQuarter();        void SelectSoftdrink(SoftDrink softDrink);        void Dispense(SoftDrink softDrink);        void SoldOut();    }
View Code

这里的四个实现类代表四种状态,整个状态切换由内部自动完成.

public abstract class AbstractSoftdrinkMacheState : ISoftdrinkState    {        protected SoftdrinkMachineContext _softdrinkMachineContext;        protected AbstractSoftdrinkMacheState(SoftdrinkMachineContext softdrinkMachineContext)        {            _softdrinkMachineContext = softdrinkMachineContext;        }        public abstract void InsertQuarter();        public abstract void SelectSoftdrink(SoftDrink softDrink);        public abstract void Dispense(SoftDrink softDrink);        public abstract void SoldOut();    }    public class NoQuarterState : AbstractSoftdrinkMacheState    {        public NoQuarterState(SoftdrinkMachineContext softdrinkMachineContext)            : base(softdrinkMachineContext)        {        }        public override void InsertQuarter()        {            _softdrinkMachineContext.SetState(_softdrinkMachineContext.HasQuarterState);        }        public override void SelectSoftdrink(SoftDrink softDrink)        {            throw new InvalidOperationException("你需要先投币");        }        public override void Dispense(SoftDrink softDrink)        {            throw new InvalidOperationException("你需要先投币");        }        public override void SoldOut()        {            throw new InvalidOperationException("你需要先投币");        }    }    public class HasQuarterState : AbstractSoftdrinkMacheState    {        public HasQuarterState(SoftdrinkMachineContext softdrinkMachineContext)            : base(softdrinkMachineContext)        {        }        public override void InsertQuarter()        {        }        public override void SelectSoftdrink(SoftDrink softDrink)        {            if (softDrink.Price > Constants.StoredMoney)                throw new InvalidOperationException("钱不够,请重新选择或补足");            _softdrinkMachineContext.SetState(_softdrinkMachineContext.SoldState);        }        public override void Dispense(SoftDrink softDrink)        {            throw new InvalidOperationException("你需要先选择饮料");        }        public override void SoldOut()        {            throw new InvalidOperationException("你需要先选择饮料");        }    }    public class SoldState : AbstractSoftdrinkMacheState    {        public SoldState(SoftdrinkMachineContext softdrinkMachineContext)            : base(softdrinkMachineContext)        {        }        public override void InsertQuarter()        {            throw new InvalidOperationException("请点击选择完毕按");        }        public override void SelectSoftdrink(SoftDrink softDrink)        {            throw new InvalidOperationException("请点击选择完毕按");        }        public override void Dispense(SoftDrink softDrink)        {            softDrink.Count--;            Constants.StoredMoney -= softDrink.Price;            _softdrinkMachineContext.S
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表