zoukankan      html  css  js  c++  java
  • 设计模式之状态模式

    状态模式是一种行为型设计模式

    当对象在不同的状态下会有不同的表现形式或者处理,那么这个时候可以使用状态模式来把复杂的判断的逻辑分散在各个类之中。

     

    环境类(Context):  定义客户感兴趣的接口。维护一个ConcreteState子类的实例,这个实例定义初始状态。

    抽象状态类(State):  定义一个接口以封装与Context的一个特定状态相关的行为。

    具体状态类(ConcreteState):  每一子类实现一个与Context的一个状态相关的行为。

    实例(Example):电梯在不同的运行状态下门的开关控制、手机账户在不同的信用级别可以欠费的额度不同、游戏中Boss在不同的状态下的属性不同

    类图:

    实例代码:

    IRoom:接口定义规范行为

     interface IRoom
        {
            void CheckIn();
            void CheckOut();
            void Unsubscribe();
            void Book();
        }

    Room:含有一个房间状态

      public class Room : IRoom
        {
            public RoomState State { get; set; }
    
            public Room()
            {
                State = new FreeState(this);
            }
    
    
            #region IRoom
    
            public void CheckIn()
            {
                State.CheckIn();
            }
    
            public void CheckOut()
            {
                State.CheckOut();
            }
    
            public void Unsubscribe()
            {
                State.Unsubscribe();
            }
    
            public void Book()
            {
                State.Book();
            }
    
            #endregion
        }

    RoomState:定义房间状态的共同行为的抽象类

     public abstract class RoomState : IRoom
        {
            protected Room RoomManagement;
    
            protected RoomState(Room room)
            {
                RoomManagement = room;
            }
    
            #region IRoom
    
            public abstract void CheckIn();
    
            public abstract void CheckOut();
    
            public abstract void Unsubscribe();
    
            public abstract void Book();
    
            #endregion
        }

    FreeState:空闲状态

     class FreeState : RoomState
        {
            public FreeState(Room room)
                : base(room)
            {
            }
    
            public override void CheckIn()
            {
                Console.WriteLine("空闲状态不能入住");
            }
    
            public override void CheckOut()
            {
                Console.WriteLine("空闲状态不能退房");
            }
    
            public override void Unsubscribe()
            {
                Console.WriteLine("空闲状态不能取消预约");
            }
    
            public override void Book()
            {
                RoomManagement.State = new BookedState(RoomManagement);
                Console.WriteLine("预约成功");
            }
        }

    BookedState:预订状态

      class BookedState : RoomState
        {
            public BookedState(Room room)
                : base(room)
            {
            }
    
            public override void CheckIn()
            {
                RoomManagement.State = new CheckInState(RoomManagement);
                Console.WriteLine("入住成功");
            }
    
            public override void CheckOut()
            {
                Console.WriteLine("预约状态不能退房");
            }
    
            public override void Unsubscribe()
            {
                RoomManagement.State = new FreeState(RoomManagement);
                Console.WriteLine("取消预约成功");
            }
    
            public override void Book()
            {
                Console.WriteLine("已经预约不能再次预约");
            }
        }

     CheckInState:入住状态

      class CheckInState : RoomState
        {
            public CheckInState(Room room)
                : base(room)
            {
            }
    
            public override void CheckIn()
            {
                Console.WriteLine("已经入住了");
            }
    
            public override void CheckOut()
            {
                RoomManagement.State = new FreeState(RoomManagement);
                Console.WriteLine("退房成功");
            }
    
            public override void Unsubscribe()
            {
                Console.WriteLine("入住状态不能取消预约");
            }
    
            public override void Book()
            {
                Console.WriteLine("入住状态不能预约");
            }
        }

     Client调用

      static void Main(string[] args)
            {
                Console.WriteLine("I.入住");
                Console.WriteLine("O.退房");
                Console.WriteLine("B.预约");
                Console.WriteLine("U.取消预约");
    
                var room = new Room();
                ConsoleKey key = ConsoleKey.A;
                while (key != ConsoleKey.Escape)
                {
                    key = Console.ReadKey(false).Key;
                    switch (key)
                    {
                        case ConsoleKey.I:
                            room.CheckIn();
                            break;
                        case ConsoleKey.O:
                            room.CheckOut();
                            break;
                        case ConsoleKey.B:
                            room.Book();
                            break;
                        case ConsoleKey.U:
                            room.Unsubscribe();
                            break;
                        default:
                            room.Book();
                            break;
                    }
                }
            }
        }

    运行结果:

    优点:将不同状态下的处理分散到各个子类当中,避免了耦合,避免了过多的判断

    缺点:状态过多的话,会产生很多子类,增加子类的复杂度

  • 相关阅读:
    poj 1984 Navigation Nightmare(带权并查集+小小的技巧)
    zoj 3261 Connections in Galaxy War(并查集逆向加边)
    poj 1733 Parity game(带权并查集)
    poj 1456 Supermarket(贪心+优先队列)
    hdu 3038 How Many Answers Are Wrong(并查集的思想利用)
    poj 1182 食物链(种类并查集 ‘初心者’)
    hdu 1182 A Bug's Life(简单种类并查集)
    hdu 4725 The Shortest Path in Nya Graph(建图+优先队列dijstra)
    CodeForces 779D. String Game(二分答案)
    poj 3169 Layout(差分约束+spfa)
  • 原文地址:https://www.cnblogs.com/XzcBlog/p/4602146.html
Copyright © 2011-2022 走看看