C#機房重構-實時檢視上機餘額(狀態模式)

劉檬發表於2018-09-04
狀態模式

這裡寫圖片描述
狀態模式:當一個物件的狀態發生改變時,允許改變其行為。當控制一個物件狀態轉換的條件表示式過於複雜時,把狀態的判斷邏輯轉移到表示不同狀態的一系列類當中,可以把複雜的判斷邏輯簡化。

具體實現

UI層

Entity.Gloable.Time = 1;//在上機操作中賦值,判斷其實時查詢餘額的次數(經過多少個小時)
 private void txtcardNo_EnabledChanged(object sender, EventArgs e)
    {
        if (txtcardNo.Enabled == false)//當確定使用者已上機,則啟動狀態模式,實時判斷餘額情況
        {
            //timer3.Enabled = true;//計時器開始執行
            timer3.Start();//啟動計時器          
        }
    }
  private void timer3_Tick(object sender, EventArgs e)
    {
        //獲得該學生的學號
        Student_info student = new Student_info();
        Line_info line = new Line_info();
        student.CardNo = Convert.ToInt32(txtcardNo.Text.Trim());
        //查詢該使用者的餘額情況
        Facade.MainFacade facade = new Facade.MainFacade();//例項化外觀
        DataTable table = facade.SelectStudent(student);
        //傳參
        line.Cash =Convert.ToDouble(table.Rows[0][7].ToString());
        line.Type = table.Rows[0][13].ToString().Trim();
        line.Cardno = student.CardNo;
        line.ConsumeTime =Gloable.Time;//獲得不斷增加的花費時間
        //每一個小時檢視其餘額
        string a = facade.InquiryState(line);
        if (a == "null")
        {
            return;//跳出
        }
        else
        {
            MessageBox.Show(a, "提示");
            if (a== "餘額不足5元,正在下機")
            {
                button1_Click(sender,e);//呼叫下機事件
                timer3.Stop();//終止實時檢視餘額情況,停止計時器
            }
        }

BLL層

public string InquiyState(Entity.Line_info line)
    {
        //獲取基本資料
        Factory.Factory fact = new Factory.Factory();
        IDAL.IBasicDate idal = fact.Opbasicdata();
        DataTable table = idal.Selectdata();
        //為實體賦值
        line.Rate = Convert.ToInt32(table.Rows[0][0]);
        line.tmpRate = Convert.ToInt32(table.Rows[0][1]);

        #region//策略模式計算花費金額
        #endregion

        //獲取學生表中的剩餘金額
        Entity.Student_info student = new Student_info();
        student.CardNo = line.Cardno;
        IDAL.IStudentIDAL idal2 = fact.Selectstudent();
        DataTable dt = idal2.Selectstudent(student);

        //將花剩餘金額傳給實體            
        line.Cash = Convert.ToDouble(dt.Rows[0][7].ToString()) - line.Consume;

        //呼叫狀態模式,判斷金額狀態
        StateModel.Context cashstate = new StateModel.Context();
        cashstate.Consume = line.Cash;//將剩餘金額賦給context的物件屬性
        string a=cashstate.WriteProgram();
        //時間+1
        Entity.Gloable.Time++;
        return a;
    }

State

public abstract class State//抽象狀態
    {
        public abstract string WriteProgram(Context context);//抽象處理請求的方法
    }

    public class Context//維護一個State的例項,並定義了當前的狀態
    {
        private State current;
        public Context()
        {
            current = new StateOne();//定義一個初始狀態
        }
        private double consume;//定義一個屬性
        public double Consume
        {
            get { return consume; }
            set { consume = value; }
        }
        public void SetState(State s)//改變初始狀態
        {
            current = s;
        }
        public string WriteProgram()//請求的處理
        {
            string a = current.WriteProgram(this);
            return a;
        }
    }
    public class StateOne : State//具體狀態
    {
        public override string WriteProgram(Context context)
        {
            string a = "null";
            if (context.Consume >= 10)
            {
                a = "null";
            }
            else
            {
                context.SetState(new StateTwo()); context.WriteProgram();
            }
            return a;
        }
    }

    public class StateTwo : State//具體狀態
    {
        public override string WriteProgram(Context context)
        {
            string a = "null";
            if (context.Consume < 10)
            {
                 a = "餘額不足10元,請儘快充值,以免影響上機!";
            }
            else
            {
                context.SetState(new StateThere()); context.WriteProgram();
            }
            return a;
        }
    }

    public class StateThere: State//具體狀態
    {
        public override string WriteProgram(Context context)
        {
            string a = "null";
            if (context.Consume < 5)
            {
                a = "餘額不足5元,正在下機";
            }
            return a;
        }

    }

總結
對於實時檢視使用者金額情況,我採用的是狀態模式,可能不是很精簡。對於這種功能的實現也推薦使用觀察者模式。觀察者模式可能會更好的在狀態發生變化時,通知所有觀察者物件,能夠 自動更新自己。這點還是很棒的!

相關文章