【设计模式】之状态模式

  • UML

  • 原型

//状态抽象类
abstract class State
    {
        public abstract void Handle(Context context);
    }
    
//状态A
 class ConcreteStateA : State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateB();
        }
    }
//状态B
class ConcreteStateB : State
    {
        public override void Handle(Context context)
        {
            context.State = new ConcreteStateA();
        }
    }
//上下文
class Context
    {
        private State state;
        public Context(State state)
        {
            this.state = state;
        }
        public void Request()
        {
            state.Handle(this);
        }
        public State State { get => state; set => state = value; }
    }
 class Program
    {
        static void Main(string[] args)
        {
            Context c = new Context(new ConcreteStateA());
            c.Request();
            c.Request();
            c.Request();
            c.Request();
        }
    }
  • 举例

一个简单的停等协议:

 //分组
    class Packet
    {
        private string data;            //数据
        private string checksum;        //数据校验和
        private int num;                //序号

        public string Data { get => data; set => data = value; }
        public string Checksum { get => checksum; set => checksum = value; }
        public int Num { get => num; set => num = value; }
    }
 //状态抽象类
    abstract class State
    {
        public abstract void Change(Context context);
    }
//终端抽象类
    abstract class Context
    {
        private State state;            //状态
        private string data;            //数据
        private string checksum;        //校验和
        private Packet packet;          //分组
        private Context other;          //对等方
        //初始化状态
        public Context(State state)
        {
            this.state = state;
        }
        //运行
        public void Run()
        {
            state.Change(this);
        }
        //rdt发送
        public bool rdt_send(string data)
        {
            return true;
        }
        //rdt接收
        public bool rdt_rcv(Packet packet)
        {
            return true;
        }
        //装包
        public Packet make_pkt(int num,string data,string checksum)
        {
            Console.WriteLine($"初始化分组[{num},{data},{checksum}]...");
            Packet packet = new Packet();
            packet.Num = num;
            packet.Data = data;
            packet.Checksum = checksum;
            return packet;
        }
        //udt发送
        public void udt_send(Packet packet)
        {
            Console.WriteLine("发送...");
            //%50的出错概率
            if (Program.random.Next(0,100)<=50)
            {
                packet.Data = "error";
                Console.WriteLine("出现bit差错!");
            }
            Other.Packet = packet;
        }
        //解包
        public void extract(Packet packet, out string data)
        {
            Console.WriteLine($"解析分组...");
            data = packet.Data;
        }
        //上传给高层
        public void deliver_data(string data)
        {
            Console.WriteLine($"{data}");
        }
        //校验和
        public bool corrupt(Packet rcvpkt)
        {
            if(!rcvpkt.Data.Equals(rcvpkt.Checksum))
            {
                Console.WriteLine("分组出错!");
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool notcorrupt(Packet rcvpkt)
        {
            if (rcvpkt.Data.Equals(rcvpkt.Checksum))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        //肯定确认
        public bool isACK(Packet rcvpkt,int num)
        {
            if (rcvpkt.Data.Equals("ACK")&&rcvpkt.Num==num)
            {
                Console.WriteLine($"收到一个{num}号肯定确认!");
                return true;
            }
            else
            {
                return false;
            }
        }
        //是0号分组还是1号分组
        public bool has_seq0(Packet packet)
        {
            if(packet.Num==0)
            {
                Console.WriteLine("收到了0号分组");
                return true;
            }else
            {
                return false;

            }
        }
        public bool has_seq1(Packet packet)
        {
            if (packet.Num == 1)
            {
                Console.WriteLine("收到了1号分组");
                return true;
            }
            else
            {
                return false;

            }
        }

        public State State { get => state; set => state = value; }
        public string Data { get => data; set => data = value; }
        public Context Other { get => other; set => other = value; }
        public Packet Packet { get => packet; set => packet = value; }
        public string Checksum { get => checksum; set => checksum = value; }
    }
 //发送端
    class Sender : Context
    {
        public Sender(State state) : base(state)
        {
        }
    }
// 发送端状态A
    class SenderStateA : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Sender:=>A");
            Console.WriteLine("---------------------");
            if (context.rdt_send(context.Data))
            {
                Packet packet = context.make_pkt(0,context.Data, context.Checksum);
                context.udt_send(packet);
                context.State = new SenderStateB();

                //接收端处理
                context.Other.Run();
            } 
        }
    }
// 发送端状态B
class SenderStateB : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Sender:=>B");
            Console.WriteLine("---------------------");
            Console.WriteLine("接收...");

            if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.isACK(context.Packet,1)))
            {
                Packet packet = context.make_pkt(0, context.Data, context.Checksum);
                context.udt_send(packet);

                context.Other.Run();
            }else if (context.rdt_rcv(context.Packet)&& context.notcorrupt(context.Packet) && context.isACK(context.Packet,0))
            {
                context.State = new SenderStateC();
            }
        }
    }
//发送端状态C
class SenderStateC : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Sender:=>C");
            Console.WriteLine("---------------------");
            if (context.rdt_send(context.Data))
            {
                Packet packet = context.make_pkt(1, context.Data, context.Checksum);
                context.udt_send(packet);
                context.State = new SenderStateD();
                //接收端处理
                context.Other.Run();
            }
        }
    }
// 发送端状态D
class SenderStateD : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Sender:=>D");
            Console.WriteLine("---------------------");
            Console.WriteLine("接收...");

            if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.isACK(context.Packet,0)))
            {
                Packet packet = context.make_pkt(1, context.Data, context.Checksum);
                context.udt_send(packet);

                context.Other.Run();
            }else if (context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.isACK(context.Packet,1))
            {
                context.State = new SenderStateA();
            }
        }
    }
//接收端
    class Receiver:Context
    {
        public Receiver(State state):base(state)
        {
        }
    }
//接收端状态A
    class RcvStateA : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Receiver:=>A");
            Console.WriteLine("------------------------");
            Console.WriteLine("接收...");

            if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.has_seq1(context.Packet)))
            {
                Packet packet = context.make_pkt(1,"ACK", "ACK");
                context.udt_send(packet);

                context.Other.Run();
            }
            else if(context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.has_seq0(context.Packet))
            {
                string data = "";
                context.extract(context.Packet,out data);
                context.deliver_data(data);
                Packet packet = context.make_pkt(0,"ACK","ACK");
                context.udt_send(packet);

                context.State = new RcvStateB();

                context.Other.Run();
            }
        }
    }
// 接收端状态B
class RcvStateB : State
    {
        public override void Change(Context context)
        {
            Console.WriteLine("Receiver:=>B");
            Console.WriteLine("------------------------");
            Console.WriteLine("接收...");

            if (context.rdt_rcv(context.Packet) && (context.corrupt(context.Packet) || context.has_seq0(context.Packet)))
            {
                Packet packet = context.make_pkt(0,"ACK", "ACK");
                context.udt_send(packet);

                context.Other.Run();
            }
            else if (context.rdt_rcv(context.Packet) && context.notcorrupt(context.Packet) && context.has_seq1(context.Packet))
            {
                string data = "";
                context.extract(context.Packet, out data);
                context.deliver_data(data);
                Packet packet = context.make_pkt(1,"ACK", "ACK");
                context.udt_send(packet);

                context.State = new RcvStateA();

                context.Other.Run();
            }
        }
    }
class Program
    {
        //产生随机数用于模仿出错概率
        public static readonly Random random = new Random();

        static void Main(string[] args)
        {
            Sender sender = new Sender(new SenderStateA());
            Receiver receiver = new Receiver(new RcvStateA());
            //建立连接
            sender.Other = receiver;
            receiver.Other = sender;

            sender.Data = "hello ";
            sender.Checksum = "hello ";
            sender.Run();
            sender.Data = "world!";
            sender.Checksum = "world!";
            sender.Run();
            Console.WriteLine("-----------SUCCESS-----------");
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值