【C#机房重构】双职责链+策咯模式+实现没钱自动下机

###前言:
机房重构终于完成了,发现最复杂的地方是下机,这次重构完成了之前VB版没有完成的功能——用户没钱自动下机!如果感觉这个功能很棒的话,那可要看看这篇博客啊!

###一、流程图
###职责链一:
time代表消费时间
unitTime代表单位递增时间
【C#机房重构】双职责链+策咯模式+实现没钱自动下机_第1张图片

###职责链二:

【C#机房重构】双职责链+策咯模式+实现没钱自动下机_第2张图片

由于会员用户与普通用户的上网单价不同,所以加上一条策略模式与两条职责链模式互相结合!

接下来给大家看一下职责链和策咯模式相互结合的相关代码!
BLL层

####策略模式:

 #region 策略模式,用来判定是普通用户,还是会员用户


    public abstract class StrategyStudentsLevel
    {
        public abstract double GetIncreaseCash(Entity.BasicData basicdata);
    }

    public class GetPerCash
    {
        StrategyStudentsLevel studentLevel;

        public double GetperCash(Entity.StudentInfo studentinfo, Entity.BasicData basic)
        {
            switch (studentinfo.Type.Trim())
            {
                case "普通用户":
                    studentLevel = new TmpStudent();
                    break;
                case "会员用户":
                    studentLevel = new FixStudent();
                    break;
            }
            return studentLevel.GetIncreaseCash(basic);
        }

    }

    //普通用户
    public class TmpStudent:StrategyStudentsLevel
    {
        double PerCash;
        public override double GetIncreaseCash(Entity.BasicData basicdata)
        {
            UserInfoBLL userBasicdata = new UserInfoBLL();
            DataTable tableBasicData = userBasicdata.SelectBasicData(basicdata);
            PerCash = Convert.ToDouble(tableBasicData.Rows[0]["tmpRate"]);
            return PerCash;
        }
    }
    //会员用户
    public class FixStudent : StrategyStudentsLevel
    {
        double perCash;
        public override double GetIncreaseCash(BasicData basicdata)
        {
            UserInfoBLL userBasicdata = new UserInfoBLL();
            DataTable tableBasicdata = userBasicdata.SelectBasicData(basicdata);
            perCash = Convert.ToDouble(tableBasicdata.Rows[0]["Rate"]);
            return perCash;
        }
    }
    #endregion

####算钱的职责链:

bLL层

   public abstract class ChainMoney
    {
        protected ChainMoney successor;

        //设置继承者
        public void SetSuccessor(ChainMoney successor)
        {
            this.successor = successor;
        }
        //处理请求的抽象方法
        public abstract void CollectMoneyy(Entity.StudentInfo studentinfo, Entity.BasicData basic,GetPerCash StudentLevelcash);
    }
    
    //准备时间内收钱
    public class CollectMoneyPre : ChainMoney
    {
        public override void CollectMoneyy(StudentInfo studentinfo, BasicData basic, GetPerCash StudentLevelcash)
        {
            //上机时间小于准备时间,不收钱
            if (Convert.ToInt32(studentinfo.Consumetime) <= Convert.ToDouble(basic.PrepareTime))
            {
                studentinfo.Consume = 0;
                studentinfo.Cash = studentinfo.Cash - studentinfo.Consume;
            }

            else
            {
                successor.CollectMoneyy(studentinfo,basic, StudentLevelcash);
            }
        }
    }
    //大于准备时间,小于递增单位上机时间,按照1.2倍价钱收费
    public class CollectMoneyLeast : ChainMoney
    {
        public override void CollectMoneyy(StudentInfo studentinfo, BasicData basic, GetPerCash StudentLevelcash)
        {
            //上机时间大于准备时间,按照单价开始收费
            if (Convert.ToInt32(studentinfo.Consumetime) > Convert.ToDouble(basic.PrepareTime)&& Convert.ToInt32(studentinfo.Consumetime) < Convert.ToDouble(basic.untiTime))
            {
                double Money = (Convert.ToDouble(studentinfo.Consumetime) / basic.untiTime + 1) * StudentLevelcash.GetperCash(studentinfo, basic) * 1.2;
                #region 避免Consume与cash出现负值
                if (Money >= 0)
                {
                    studentinfo.Consume = Money;
                }
                else
                {
                    studentinfo.Consume = studentinfo.Cash;
                }

                if ((studentinfo.Cash - studentinfo.Consume) >= 0)
                {
                    studentinfo.Cash = (studentinfo.Cash - studentinfo.Consume);
                }
                else
                {
                    studentinfo.Cash = 0;
                }
                #endregion
            }
            else
            {
                successor.CollectMoneyy(studentinfo, basic, StudentLevelcash);
            }
        }
    }


    //非单位递增时间收钱

    public class CollectMoneyNormal : ChainMoney
    {
        public override void CollectMoneyy(StudentInfo studentinfo, BasicData basic, GetPerCash StudentLevelcash)
        {
            //上机时间大于单位时间,按照单价开始收费
            if (Convert.ToInt32(studentinfo.Consumetime)> Convert.ToInt32(basic.untiTime))
            {
                 double Money= (Convert.ToInt32(studentinfo.Consumetime) / basic.untiTime + 1) * StudentLevelcash.GetperCash(studentinfo, basic);
                #region 避免Consume与cash出现负值

                if (Money>=0)
                {
                    studentinfo.Consume = Money;
                }
                else
                {
                    studentinfo.Consume = studentinfo.Cash;
                }
                            
                if (studentinfo.Cash - studentinfo.Consume >= 0)
                 {
                    studentinfo.Cash = studentinfo.Cash - studentinfo.Consume;
                 }
                 else
                 {
                   studentinfo.Cash = 0;
                 }

                #endregion
            }
            else
            {
                successor.CollectMoneyy(studentinfo, basic, StudentLevelcash);
            }
        }
    }

外观层

 public class StudentConsumeFacade
{
    public void Consume(Entity.StudentInfo studentinfo,Entity.BasicData basicdata,BLL.GetPerCash studentLevelCash)
    {
       // BLL.StrategyStudentsLevel studentLevel;
        //实例化收钱的方式
        BLL.ChainMoney PerConsume = new BLL.CollectMoneyPre();
        BLL.ChainMoney LeastConsume = new BLL.CollectMoneyLeast();
        BLL.ChainMoney NormalConsume = new BLL.CollectMoneyNormal();

        //设置职责链的上下家
        PerConsume.SetSuccessor(LeastConsume);
        LeastConsume.SetSuccessor(NormalConsume);

        //职责链的首家开始提交请求
        PerConsume.CollectMoneyy(studentinfo,basicdata, studentLevelCash);
    }
}

####根据用户剩余的余额有不同的显示的职责链
bll层

public abstract class ChainOffTime
    {
      
        protected ChainOffTime successor;
        //设置继承者
        public void SetSuccessor(ChainOffTime successor)
        {
            this.successor = successor;
        }
        public abstract int ConsumeTime(Entity.StudentInfo studentinfo, Entity.BasicData basic,GetPerCash getpercash);
    }

    public class TimeTenMinute : ChainOffTime
    {
        public override int ConsumeTime(Entity.StudentInfo studentinfo, Entity.BasicData basic,GetPerCash getpercash)
        {                              
                if ( (Convert.ToInt32(studentinfo.timeRemain) - 590)==0)
                {
                    int tenMinute = 1;
                    return tenMinute;
                }

            else
            {
                successor.ConsumeTime(studentinfo,basic, getpercash);
                return fifteenSecond.fifteenSecond1;
            }
        }
   }

    public class fifteenSecond : ChainOffTime
    {
        public static int fifteenSecond1;
         public override int ConsumeTime(Entity.StudentInfo studentinfo, Entity.BasicData basic, GetPerCash getpercash)
         {        
            if (Convert.ToInt32(studentinfo.timeRemain) - 15== 0)
            {
                fifteenSecond1 = 2;
                return fifteenSecond1;
            }
            else
            {
                return 0;
            }
        }
     }      

外观层

public class StudentInfoTimeFacade
{
    public int RemainTime(Entity.StudentInfo studentinfo,Entity.BasicData basic, BLL.GetPerCash studentLevelCash)
    {
        BLL.ChainOffTime tenMinute = new BLL.TimeTenMinute();
        BLL.ChainOffTime fifteenSecond = new BLL.fifteenSecond();

        //设置职责链的上家
        tenMinute.SetSuccessor(fifteenSecond);          
        int Result= tenMinute.ConsumeTime( studentinfo,basic, studentLevelCash);
        return Result;
    }
}
根据用户剩余的余额有不同的显示的职责链,之所以返回1和2是因为这些需要在UI层进行判断,显示出不同的框!

UI层全部代码:

public partial class frmMain : Form
{
    #region 定义全局对象以及变量
    public static double cash;       //学生卡上的余额
    public static double limitCash;  //最小上机金额
    public static double unitTime;   //递增单位时间
    public static double time;       //计算
    int TimeCount = 0;    //定义一个long型变量   
    public delegate void setControlValue(long value);//定义一个委托

    //实体层与外观层
    Entity.BasicData basic = new Entity.BasicData();
    Entity.StudentInfo studentinfo = new Entity.StudentInfo();
    Facade.StudetnOnOffComputerFacade FstudentOnOff = new Facade.StudetnOnOffComputerFacade(); 
    #endregion

    public frmMain()
    {
        #region 界面初始化
        InitializeComponent();
   
        lblUserName.Text = frmLogin.userid;
        studentinfo.Cardno = Convert.ToInt32(frmLogin.userid);

        DataTable table = FstudentOnOff.SelectStudentCash(studentinfo);
        lblNowBalance.Text = Convert.ToString(table.Rows[0][0]);

        cash = Convert.ToDouble(table.Rows[0][0]);

        TimCosume.Stop();
        lblHavaOnline.Visible = false;
        lblHaveOnlineWord.Visible = false;

        btnOffLine.Enabled = false;

        #endregion
        txtInformation.Visible = false;
    }
    private void groupBoxup_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
    {
        e.Graphics.Clear(this.BackColor);
    }

    //实时显示日期和时间
    private void TimNowDataTime_Tick(object sender, EventArgs e)
    {
        lblNOwdata.Text = DateTime.Now.ToShortDateString().ToString();

        lblNowTime.Text = DateTime.Now.ToLongTimeString().ToString();
    }


    //上机
    public void btnOnline_Click(object sender, EventArgs e)
    {         
        #region 调用表basicdata中的数据,赋值到实体层
        
        Facade.UserInfoFacade Fbasicdata = new Facade.UserInfoFacade();
        DataTable tableBasicdata = Fbasicdata.SelectBasicData(basic);
        basic.Fixrate = Convert.ToInt32(tableBasicdata.Rows[0]["Rate"]);
        basic.tmpRate = Convert.ToInt32(tableBasicdata.Rows[0]["tmpRate"]);
        basic.untiTime = Convert.ToInt32(tableBasicdata.Rows[0]["unitTime"]);
        basic.leastTime = Convert.ToInt32(tableBasicdata.Rows[0]["leastTime"]);
        basic.PrepareTime = Convert.ToInt32(tableBasicdata.Rows[0]["PrepareTime"]);

        limitCash = Convert.ToDouble(tableBasicdata.Rows[0]["limitCash"]);
        unitTime = Convert.ToDouble(tableBasicdata.Rows[0]["unitTime"]);
        #endregion

        if (cash < limitCash)
            {
                MessageBox.Show("余额不足,不可以上机,请找操作员充值");
            }
            else
            {
            btnOffLine.Enabled = true;
            btnOnline.Enabled = false;

               #region //更新line表和Online表

                DataTable table = FstudentOnOff.SelectStudentInfo(studentinfo);

                string text = table.Rows[0][0].ToString();
                studentinfo.Cardno = Convert.ToInt32(frmLogin.userid);
                studentinfo.Studentno = Convert.ToInt32(table.Rows[0]["Studentno"]);
                studentinfo.Studentname = table.Rows[0]["studentName"].ToString();
                studentinfo.Sex = table.Rows[0]["sex"].ToString();
                studentinfo.Department = table.Rows[0]["department"].ToString();
                studentinfo.Ondate = DateTime.Now.ToShortDateString().ToString();
                studentinfo.Ontime = DateTime.Now.ToShortTimeString().ToString();
                studentinfo.Type = table.Rows[0]["type"].ToString();
                studentinfo.Computer = System.Environment.UserName;
                studentinfo.Cash = Convert.ToInt32(table.Rows[0]["cash"]);
                studentinfo.Ischeck = "未结账";

                FstudentOnOff.InsertStudentLine(studentinfo);
                FstudentOnOff.InsertStudentOnLine(studentinfo);
                
            #endregion

                lblHavaOnline.Visible = true;
                lblHaveOnlineWord.Visible = true;
                TimCosume.Start();
            MessageBox.Show("您已上机");

            Facade.StudentInfoTimeFacade FConsumeTime = new Facade.StudentInfoTimeFacade();
            BLL.GetPerCash getpercash = new GetPerCash();

            //计算
            time = (Convert.ToDouble(cash) / Convert.ToDouble(getpercash.GetperCash(studentinfo, basic))) * Convert.ToInt32(basic.untiTime) * 60;
        }              
    }

    #region time控件利用委托实现时间从00:00:00开始记时间

    //实现了每一秒加上1
    private void TimCosume_Tick(object sender, EventArgs e)
    {
        this.Invoke(new setControlValue(ShowTime),TimeCount);//前边必须是一个委托的方法,后边是一个整型的数据类型!
        TimeCount++;

        Entity.BasicData basic = new Entity.BasicData();
        studentinfo.Consumetime = (TimeCount / 60 + 1);

        /*
         *一条用来实现学生们自己下机,所剩钱为10分钟的时候,出现提示条,所剩时间为15秒的时候,
         *弹出框,然后倒计时!最后自己下机
        */
        Facade.StudentInfoTimeFacade FConsumeTime = new Facade.StudentInfoTimeFacade();
        BLL.GetPerCash getpercash = new GetPerCash();
        //不同的int会出现不同的窗体,10分钟的窗体,与15秒钟的窗体
        time--;
        studentinfo.timeRemain = time;

        int TimeInformation = FConsumeTime.RemainTime(studentinfo, basic, getpercash);

        if (TimeInformation == 1)
        {
            txtInformation.Visible = true;
            timerTxtInformation.Start();
        }
        if (TimeInformation == 2)
        {
            TimCosume.Stop();
            frmOffCountDown frmDownOline = new frmOffCountDown();
            frmDownOline.Show();
            Facade.StudetnOnOffComputerFacade FstudentOnOff = new Facade.StudetnOnOffComputerFacade();

            #region 更新表line和Online
            //删除Online表中的正在上机的信息
            FstudentOnOff.DeleteStudentOnLine(studentinfo);

            //更新line中的信息         
            studentinfo.Offdate = DateTime.Now.ToShortDateString();
            studentinfo.Offtime = DateTime.Now.ToShortTimeString();
            FstudentOnOff.UpdaStudentLine(studentinfo);
            #endregion

            #region 一条判断学生在上机,根据不同的时间消费金额不同,然后进行收费
            studentinfo.Consumetime = (TimeCount / 60 + 1);

            Facade.StudentConsumeFacade FconsumeMoney = new Facade.StudentConsumeFacade();            
            FconsumeMoney.Consume(studentinfo, basic, getpercash);
            #endregion
            //更新表StudentInfo中的cash
            FstudentOnOff.UpdateStudentInfoCash(studentinfo);
            TimCosume.Stop();
        }
    }

    /// 
    /// 方法显示时间格式
    /// 
    /// 
    private void ShowTime(long t)
    {            
        TimeSpan temp = new TimeSpan(0, 0, (int)t);
        lblHavaOnline.Text = string.Format("{0:00}:{1:00}:{2:00}", temp.Hours, temp.Minutes, temp.Seconds);
    }

    #endregion
    //下机
    private void btnOffLine_Click(object sender, EventArgs e)
    {
        btnOnline.Enabled = false;
        btnOffLine.Enabled = true;
        Facade.StudetnOnOffComputerFacade FstudentOnOff = new Facade.StudetnOnOffComputerFacade();

        #region 更新表line和Online
        //删除Online表中的正在上机的信息
        FstudentOnOff.DeleteStudentOnLine(studentinfo);
        //studentinfo.Consumetime = TimeCount / 60 + 1;

       // Entity.UserInfo userinfo = new Entity.UserInfo();

        //更新line中的信息         
        studentinfo.Offdate = DateTime.Now.ToShortDateString();
        studentinfo.Offtime = DateTime.Now.ToShortTimeString();
        FstudentOnOff.UpdaStudentLine(studentinfo);
        #endregion

        #region 一条判断学生在上机,根据不同的时间消费金额不同,然后进行收费
        studentinfo.Consumetime = (TimeCount / 60 + 1);
           
        Facade.StudentConsumeFacade FconsumeMoney = new Facade.StudentConsumeFacade();
        BLL.GetPerCash getpercash = new GetPerCash();
        FconsumeMoney.Consume(studentinfo, basic, getpercash);
        #endregion

        //更新表StudentInfo中的cash
        FstudentOnOff.UpdateStudentInfoCash(studentinfo);            
        TimCosume.Stop();
        MessageBox.Show("下机成功");
    }
    #region timer控件实现text控件的闪烁
    private void timerTxtInformation_Tick(object sender, EventArgs e)
    {
        if (txtInformation.BackColor == Color.Blue)
        {
            txtInformation.BackColor = Color.White;
        }
        else
        {
            txtInformation.BackColor = Color.Blue;
        }
    } 
    #endregion
}

界面:
【C#机房重构】双职责链+策咯模式+实现没钱自动下机_第3张图片

因为下机太复杂,博客有点长,不好意思,大家随意看!

你可能感兴趣的:(C#学习,C#)