16/23 状态模式

状态模式(State Pattern)

类的行为是基于它的状态改变的,在状态模式中,我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。

1.简单案例:红绿灯

现在我们有一个红绿灯变化,红、黄、绿,不同灯时不同的提示,当然颜色就是提示,每一个灯之后切换一下,最后形成闭环,比如:红->黄->绿->红

1.1基于上述我们简单实现如下:

public class LightFactory
{
   public static LightColor CurrentLightColor { get; set; }
    public static void Show()
    {
        switch (CurrentLightColor)
        {
            case LightColor.Red:
                Console.WriteLine("红灯停....");
                break;
            case LightColor.Yellow:
                Console.WriteLine("黄灯亮了等一等....");
                break;
            case LightColor.Green:
                Console.WriteLine("绿灯行....");
                break;
        }
    }
    public static void Trun()
    {
        Console.WriteLine("******变灯了...");
        switch (CurrentLightColor)
        {
            case LightColor.Red:
                CurrentLightColor = LightColor.Yellow;
                break;
            case LightColor.Yellow:
                CurrentLightColor = LightColor.Green;
                break;
            case LightColor.Green:
                CurrentLightColor = LightColor.Red;
                break;
        }
    }
}
public enum LightColor
{
    Red=0,
    Yellow=1,
    Green=2,
}

/// 界面调用

private void btnSimple_Click(object sender, EventArgs e)
{
    LightFactory.CurrentLightColor = LightColor.Green;
    LightFactory.Show();
    LightFactory.Trun();
    LightFactory.Show();
    LightFactory.Trun();
    LightFactory.Show();
    LightFactory.Trun();
    LightFactory.Show();
    LightFactory.Trun();
}

界面效果如下:

在这里插入图片描述

1.2批斗环节…

  1. 代码严重违背了单一原则,对于单一的颜色要做的事情耦合在一起,代码结构不清晰
  2. 个人认为架构师的职责不是为了当下,而是为了变化扩展,现在需要陆续增加灯,蓝灯以及白灯,基于此当发生如下改动时则又违背了开闭原则,且对于灯的管理混乱,设想我们现在灯增加10个,基本上就是杂乱无章的。
    • 蓝灯放在绿灯之后
    • 白灯放在红灯和黄灯中间

1.3 状态模式

首先先抽象成员,封装对象

public interface LightBase
{
    LightColor CurrentLightColor { get; }
    void Show();
    void Trun();
}

public class RedLight : LightBase
{
    public LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Red;
        }
    }
    public void Show()
    {
        Console.WriteLine("红灯停....");
    }
    public void Trun()
    {
        throw new NotImplementedException();
    }
}

public class YellowLight : LightBase
{
    public LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Yellow;
        }
    }
    public void Show()
    {
        Console.WriteLine("黄灯亮了等一等....");
    }
    public void Trun()
    {
        throw new NotImplementedException();
    }
}

public class GreenLight : LightBase
{
    public LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Green;
        }
    }
    public void Show()
    {
        Console.WriteLine("绿灯行....");
    }
    public void Trun()
    {
        throw new NotImplementedException();
    }
}

然后基于上述代码,我们来填充状态控制,最终代码如下:

public abstract class LightBase
{
    public abstract LightColor CurrentLightColor { get; }
    public abstract void Show();
   public abstract void Trun(LightContext pLightContext);
}

public class RedLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Red;
        }
    }
    public override void Show()
    {
        Console.WriteLine("红灯停....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new YellowLight();
    }
}

public class YellowLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Yellow;
        }
    }
    public override void Show()
    {
        Console.WriteLine("黄灯亮了等一等....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new GreenLight();
    }
}

public class GreenLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Green;
        }
    }
    public override void Show()
    {
        Console.WriteLine("绿灯行....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new RedLight();
    }
}

public class LightContext
{
    public LightBase CurrentLightBase
    {
        get;
        set;
    }
    public void Show()
    {
        CurrentLightBase.Show();
    }
    public void Trun()
    {
        CurrentLightBase.Trun(this);
    }
}

界面调用:
private void btnState_Click(object sender, EventArgs e)
{
    LightContext pLightContext = new LightContext();
    pLightContext.CurrentLightBase = new GreenLight();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
}

效果如下:

在这里插入图片描述

基于上述的例子我们增加代码如下:


public enum LightColor
{
    Red=0,
    White = 1,
    Yellow =2,
    Green = 3,
    Blue = 4,
}

public abstract class LightBase
{
    public abstract LightColor CurrentLightColor { get; }
    public abstract void Show();
   public abstract void Trun(LightContext pLightContext);
}
public class RedLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Red;
        }
    }
    public override void Show()
    {
        Console.WriteLine("红灯停....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new Whiteight();
    }
}
public class Whiteight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.White;
        }
    }
    public override void Show()
    {
        Console.WriteLine("白灯默哀....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new YellowLight();
    }
}
public class YellowLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Yellow;
        }
    }
    public override void Show()
    {
        Console.WriteLine("黄灯亮了等一等....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new GreenLight();
    }
}
public class GreenLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Green;
        }
    }
    public override void Show()
    {
        Console.WriteLine("绿灯行....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new BlueLight();
    }
}
public class BlueLight : LightBase
{
    public override LightColor CurrentLightColor
    {
        get
        {
            return LightColor.Blue;
        }
    }
    public override void Show()
    {
        Console.WriteLine("蓝灯减速....");
    }
    public override void Trun(LightContext pLightContext)
    {
        pLightContext.CurrentLightBase = new RedLight();
    }
}
public class LightContext
{
    public LightBase CurrentLightBase
    {
        get;
        set;
    }
    public void Show()
    {
        CurrentLightBase.Show();
    }
    public void Trun()
    {
        CurrentLightBase.Trun(this);
    }
}

界面调用
private void btnState_Click(object sender, EventArgs e)
{
    LightContext pLightContext = new LightContext();
    pLightContext.CurrentLightBase = new GreenLight();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
    pLightContext.Show();
    pLightContext.Trun();
}

在这里插入图片描述

只有动手之后才会发下改起来有多简单,动手先模拟一下业务变化时修改代码

ps:单纯对于这个例子,我们发现在public abstract void Trun(LightContext pLightContext);中每次增加或删除修改时我们都要进行修改相邻类,那么我们有没有办法将该信息修改,在这个 案例中是可以的,应为每个LightBase中都有一个LightColor而LightColor有一个枚举,我们是否可以用LightColor的顺序形成闭环操作对象的状态转换呢?答案当然时肯定的。

复杂案例

[此案例只叙述一下]
将上述案例进行变形,现在当红灯时可以变化为蓝灯或者白灯,白灯可以变化为蓝灯或者黄灯,黄灯可以变化为绿灯或者蓝灯…而变化时用户的输入,那么这个时候再回到简单实现中的工厂中去尝试流转改变试试…
445574888)]

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 点我我会动 设计师:白松林 返回首页