0
点赞
收藏
分享

微信扫一扫

设计模式系列之状态模式(3)


设计模式系列之状态模式(3)_System

在设计模式之状态模式中对状态模式进行了介绍,留下了一个悬念,如何彻底干掉if/else。本文主要解决这个问题。

状态转化和维护

在上一篇文章中,状态的维护在上下文中,这就不可避免的使用到if/else进行判断。如果把状态的维护放在状态的处理类中,那就可以避免大连的if/else使用了。

状态处理类中维护状态: 当每一个状态对象处理完自身的状态所对应的功能喉,咳哟根据需要指定后继的状态,以便让应用能够正确处理后续的请求。

时序图

类图和上面的文章一样,主要看时序图,能够很方便理解上面的内容。

设计模式系列之状态模式(3)_时序图_02

恶意投票状态和黑名单状态于这个类似,时序图中没有画出。

代码实现

客户端代码

先看客户端,使用模式和没有使用模式进行对比,没有使用模式的实现在设计模式之状态模式。

Console.WriteLine("不用模式的运行结果:");
        VoteManager voteManager = new VoteManager();
        for (int i = 0; i < 10; i++)
        {
            voteManager.Vote("Burning", "sxy");
        }

        Console.WriteLine("\n");
        Console.WriteLine("使用状态模式的运行结果:");
        VoteManagerContext vmc = new VoteManagerContext();  

       for (int i = 0; i < 10; i++)
       {
            vmc.Vote("Burning", "sxy");
       }

上下文实现

由于把状态的维护放在了状态处理类中,上下文没有的大连的if/else。主要增加了用户状态类字典,方便状态维护。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class VoteManagerContext
    {
        // 投票状态
        private VoteState voteState;

        // 投票用户 投票选项
        private Dictionary<String, String> dictionaryVote = new Dictionary<String, String>();

        // 投票用户 投票数量
        private Dictionary<String, int> dictionaryVoteCount = new Dictionary<string, int>();

        // 投票用户 状态
        private Dictionary<String, VoteState> dictionaryVoteState = new Dictionary<string, VoteState>();

        //保存投票的数量
        private int count = 0;

        public Dictionary<String, String> getDictionaryVote()
        {
            return dictionaryVote;
        }

        public Dictionary<String, VoteState> getDictionaryVoteState()
        {
            return dictionaryVoteState;
        }

        public Dictionary<String, int> getDictionaryVoteCount()
        {
            return dictionaryVoteCount;
        }

        public void Vote(String user, String item)
        {
            bool contain = dictionaryVoteState.ContainsKey(user);
            if (!contain)
            {
                voteState = new NormalVoteState();
                dictionaryVoteState.Add(user, voteState);
            }
            voteState = dictionaryVoteState[user];
            count = count + 1;
            if (!dictionaryVoteCount.ContainsKey(user))
            {
                dictionaryVoteCount.Add(user, count);

            }
            dictionaryVoteCount[user] = count;
            voteState.Vote(user, item, this);
        }
    }
}

正常投票状态

添加后续状态(重复投票)的维护。

namespace ConsoleApp1
{
    internal class NormalVoteState : VoteState
    {
        public void Vote(string user, string item, VoteManagerContext voteManagerContext)
        {
            Console.WriteLine("投票成功");
            Dictionary<String, int> dictionaryVoteCount = voteManagerContext.getDictionaryVoteCount();
            if (dictionaryVoteCount[user] == 1)
            {
                voteManagerContext.getDictionaryVote().Add(user, item);
            }
            Dictionary<String, int> voteCount =  voteManagerContext.getDictionaryVoteCount();
            if (voteCount[user] < 3)
            {
                voteManagerContext.getDictionaryVoteState()[user] =  new RepeatNoteState();
            }
        }
    }
}

重复投票状态

添加后续状态(恶意投票)的维护。

namespace ConsoleApp1
{
    internal class RepeatNoteState : VoteState
    {
        public void Vote(string user, string item, VoteManagerContext voteManagerContext)
        {
            Console.WriteLine("请不要重复投票");
            Dictionary<String, int> voteCount = voteManagerContext.getDictionaryVoteCount();
            if (voteCount[user] < 8)
            {
                voteManagerContext.getDictionaryVoteState()[user] = new SpiteVoteState();
            }
        }
    }
}

恶意投票状态

添加后续状态(黑名单)的维护。

namespace ConsoleApp1
{
    internal class SpiteVoteState : VoteState
    {
        public void Vote(string user, string item, VoteManagerContext voteManagerContext)
        {
            bool contain = voteManagerContext.getDictionaryVote().ContainsKey(user);
            if (contain)
            {
                voteManagerContext.getDictionaryVote().Remove(user);
            }
            Console.WriteLine("存在恶意投票行为,取消投票资格");
            Dictionary<String, int> voteCount = voteManagerContext.getDictionaryVoteCount();
            if (voteCount[user] >= 7)
            {
                voteManagerContext.getDictionaryVoteState()[user] = new BlackVoteState();
            }
        }
    }
}

黑名单状态

不需要添加后续状态维护。

namespace ConsoleApp1
{
    internal class BlackVoteState : VoteState
    {
        public void Vote(string user, string item, VoteManagerContext voteManagerContext)
        {
            Console.WriteLine("加入黑名单,禁止登陆系统");
        }
    }
}

运行结果

设计模式系列之状态模式(3)_时序图_03

完全相同,代码量增加了很多,同时避免的大连的if/else条件判断。

扩展

8到9次,给个机会,禁止3天内登陆系统。添加相应的类,修改以下前面的状态类的后继状态即可。这里主要是新添加的类。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    internal class BlackVWarnoteState : VoteState
    {
        public void Vote(string user, string item, VoteManagerContext voteManagerContext)
        {
            bool contain = voteManagerContext.getDictionaryVote().ContainsKey(user);
            if (contain)
            {
                voteManagerContext.getDictionaryVote().Remove(user);
            }
            Console.WriteLine("禁止3天内登陆系统");
            Dictionary<String, int> voteCount = voteManagerContext.getDictionaryVoteCount();
            if (voteCount[user]  >= 9)
            {
                voteManagerContext.getDictionaryVoteState()[user] = new BlackVoteState();
            }
        }
    }
}

运行结果

设计模式系列之状态模式(3)_状态模式_04

本质

根据状态来分离和选择行为

下载最后

通过工厂+状态也能够实现消灭if/else,并且更加完美。

公众号

设计模式系列之状态模式(3)_System_05


举报

相关推荐

0 条评论