C#机房重构-学生下机使用策略模式与简单工厂结账

前言:
学生下机结账就象网吧的客户下机一样,下机就对此客户进行计算消费金额。根据不同的客户类型,对应着不同的算法。比如:这个机房管理系统的用户,有两种类型,临时用户和固定用户。

概念:
策略模式:
优点
定义一些列的算法,根据客户端的选择来实例化具体的算法类。
缺点
把选择部分转移到了客户端,每次更改要使用的算法都得在客户端做选择。

简单工厂与策略模式结合
优点
这样的话利用简单工厂的特性,又把客户端的选择部分 转移到了策略内部进行了。 这样每次,根据客户端传进来的需求在策略内部选择具体的算法。
缺点
严格意义上来说简单工厂不算是一个模式,因为简单工厂既不符合开闭原则,也不符合单一原则。而且每次扩展,都需要破坏原来的封装。

类图:
一张图胜过千言万语,通过这张图可以非常清晰的看清楚策略与策略内容的一个具体关系。
在这里插入图片描述
代码实现:
ashSuper(抽象的策略类)

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace UI
{
    /// <summary>
    /// 抽象的算法类
    /// </summary>
 public abstract class CashSuper
 {
        /// <summary>
        /// 计算结果
        /// </summary>
        ///<param name="TiemSolt">上机时间</param>
        /// <returns>计算结果</returns>
        public abstract double GetConsumeMoney(double TiemSolt);
 }
}

CashVIP(固定用户策略类)

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

namespace UI
{
    /// <summary>
    /// 固定用户
    /// </summary>
 public   class CashVIP:CashSuper
    {
        /// <summary>
        /// 每小时收费标准
        /// </summary>
        private double moneuyRebate = 2d;
        /// <summary>
        /// 给moneyRebate赋值
        /// </summary>
        /// <param name="moneyRebate">收费标准</param>
        public CashVIP(double moneyRebate)
        {
            this.moneuyRebate =moneyRebate;
        }
        /// <summary>
        /// 计算收费结果
        /// </summary>
        /// <param name="TiemSolt">消费时间</param>
        /// <returns>结果</returns>
        public override double GetConsumeMoney(double TiemSolt)
        {
            return moneuyRebate * (TiemSolt/60.0);
        }
    }
}
CashNorma(临时用户的策略类)
 

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

namespace UI
{
    /// <summary>
    /// 临时用户收费算法
    /// </summary>
    public class CashNormal : CashSuper
    {
        /// <summary>
        /// 每小时收费标准
        /// </summary>
        private double moneyRebate = 1d;
        /// <summary>
        /// 给moneyRebat赋值
        /// </summary>
        /// <param name="moneyRebate">每小时收费标准</param>
        public CashNormal(double moneyRebate)
        {
            this.moneyRebate = moneyRebate;
        }
        /// <summary>
        /// 计算临时用户消费金额
        /// </summary>
        /// <param name="TiemSolt">消费时间</param>
        /// <returns>消费金额</returns>
        public override double GetConsumeMoney(double TiemSolt)
        {
            return moneyRebate * (TiemSolt/60.0);   
        }
    }
}

策略模式与简单工厂的结合

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Enitity;
namespace UI
{
    /// <summary>
    /// 根据条件选择收费标准
    /// </summary>
public class StuCashContext
    {
        CashSuper cs = null;//声明一个CashSuper类
        /// <summary>
        /// 选择收费算法
        /// </summary>
        /// <param name="type">用户类型</param>
        /// <param name="Mylist">收费标准</param>
        public  StuCashContext(string type,int Cash)
        {
           
            //根据用户类型,选择不同的收费算法。
            switch (type)
            {
                case "固定用户":
                    CashVIP cs1 = new CashVIP(Convert.ToDouble(Cash));
                    cs = cs1;//把实例化的固定用户赋值给抽象层策略类
                    break;
                case "临时用户":
                    CashNormal cs0 = new CashNormal(Convert.ToDouble(Cash));
                    cs = cs0;
                    break;
            }//end switch
             
        }
        /// <summary>
        /// 计算分结果
        /// </summary>
        /// <param name="TimeSolt">消费时间</param>
        /// <returns></returns>
        public double GetResult(double TimeSolt)
        {
            //返回计算结果
            return cs.GetConsumeMoney(TimeSolt);
        }
    }

}

UI层调用

   #region 计算余额
            //实例化策略模式与简单工厂,用于计算消费金额
            StuCashContext StuCsh = new StuCashContext(studenttype.Text,StuReluet);
            
            #region 判断是否收费
            //根据上机时间,判断是否收费
            if (int.Parse(label8.Text) >6 && int.Parse(label8.Text)<60)
            {
                //接收消费金额,超过上机准备时间按一小时计算
                 Money = StuCsh.GetResult(60);

            }
            else if(int.Parse(label8.Text)>60)
            {
                //否则按照上机时间计算
                Money = StuCsh.GetResult(double.Parse(label8.Text));
            }
            //end if
             //显示目前消费金额
            #endregion
           

posted @ 2019-12-24 08:48  康世行  阅读(44)  评论(0编辑  收藏  举报