zoukankan      html  css  js  c++  java
  • 项目重构--使用策略模式

      大家先看下下面这段代码有什么感受?

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.ServiceModel;
    using PCI_ClassLibrary;
    using System.Windows.Threading;
    using Oland.HIP.Common.Entities;
    using Oland.HSS.Common;
    using Oland.HIP.Common.Enums;
    using System.Windows.Media.Imaging;
    namespace Oland.HSS.InHospital
    {
        public class BaseSwingCardWindow : BaseWindow
        {
            //检测读卡器是否打开 
            public bool IsOpened { get; set; }
    
            //刷卡的模块
            public Modules myModule { get; set; }
    
            //刷卡类型
            public CardTypeMode CardType;
    
            //刷卡定时器
            DispatcherTimer SwingTimer;
    
            //切换背景
            //public BitmapImage bgImg = new BitmapImage(new Uri("../Picture/main/yhk.png",UriKind.Relative));
            public BitmapImage bgImg;
            //切换提示信息
            public string tipMsg = "请按提示刷您的签约
    银行卡";
            public BaseSwingCardWindow() { }
            public BaseSwingCardWindow(CardTypeMode CardType)
            {
                //Load事件播放语音
                this.Loaded += new RoutedEventHandler(BaseSwingCardWindow_Loaded);
                //窗口关闭,停止定时器
                this.Closed += (object sender, EventArgs e) => { this.SwingTimer.IsEnabled = false; };
    
                SwingTimer = new DispatcherTimer();
                SwingTimer.Interval = TimeSpan.FromSeconds(1);
                SwingTimer.Tick += new EventHandler(SwingTimer_Tick);
                SwingTimer.IsEnabled = true;
    
                this.CardType = CardType;
    
                string strError = "";
    
                //硬件检测显示进度条
                 Common.CommWindow.BeginProgressBar("",0);
                
    
                if (CardType == CardTypeMode.BankCard || CardType == CardTypeMode.MedicalCard)
                {
                    if (Oland.HSS.Common.OperationPCI.CheckDevice(out strError, DeviceName.ReadCard3in1))
                    {
                        IsOpened = true;
                        string error;
                        Oland.HSS.Common.OperationPCI.EnableCardIn(out error);
    
                        //切换为就诊卡刷卡动画
                        if (CardType == CardTypeMode.MedicalCard)
                        {
                            bgImg = new BitmapImage(new Uri("../Pictures/main/jzk.png", UriKind.Relative));
                            tipMsg = "请按提示刷您的就诊卡";
                        }
                    }
                    else
                    {
                        IsOpened = false;
                        Common.CommWindow.EndProgressBar();
                        Common.CommWindow.ShowDialogTip("读卡器故障", strError);
                        return;
                    }
                }
                else
                {
                    if (HSS.Common.OperationPCI.CheckDevice(out strError, DeviceName.IDCard))
                    {
                        //切换身份证背景
                        bgImg = new BitmapImage(new Uri("../Pictures/main/sfz.png", UriKind.Relative));
                        tipMsg = "请按提示刷您的身份证";
                    }
                    else
                    {
                        IsOpened = false;
                        Common.CommWindow.EndProgressBar();
                        Common.CommWindow.ShowDialogTip("","身份证读卡器故障,请联系柜台!");
                        return;
                    }
                }
    
                //检测小票打印机
                if (!HSS.Common.OperationPCI.CheckDevice(out strError, DeviceName.Printer))
                {
                    IsOpened = false;
                    Common.CommWindow.EndProgressBar();
                    Common.CommWindow.ShowDialogTip("","小票打印机故障,请联系柜台!");
                }
                Common.CommWindow.EndProgressBar();
            }
    
            void BaseSwingCardWindow_Loaded(object sender, RoutedEventArgs e)
            {
                switch (CardType)
                {
                    case CardTypeMode.IDCard:
                        HSS.Common.OperationPCI.SetVoicesUrl("Voices/请刷二代身份证.wav");
                        break;
                    case CardTypeMode.MedicalCard:
                        HSS.Common.OperationPCI.SetVoicesUrl("Voices/请刷就诊卡.wav");
                        break;
                    case CardTypeMode.BankCard:
                        HSS.Common.OperationPCI.SetVoicesUrl("Voices/请刷签约银行卡.wav");
                        break;
                    case CardTypeMode.MedicalInsuranceCard:
                        break;
                    case CardTypeMode.HealthCard:
                        break;
                    default:
                        break;
                }
            }
    
            //定时刷新
            void SwingTimer_Tick(object sender, EventArgs e)
            {
                if (SwingCarding(CardType))
                {
                    SwingTimer.IsEnabled = false;
    
                    TransWin();
                }
            }
    
            //用于基类重写,实现刷卡后跳转功能
            public virtual void TransWin()
            {
            }
    
            /// <summary>
            /// 刷卡
            /// </summary>
            /// <param name="type">刷卡类型</param>
    
            public bool SwingCarding(CardTypeMode type)
            {
                string strError = null;
    
                CardInfo cardInfo = new CardInfo();
    
                switch (type)
                {
                    case CardTypeMode.IDCard://刷身份证
    
                        IDCard_XZX_DKQ116D.IDCardData IDCardInfo = new IDCard_XZX_DKQ116D.IDCardData();
                        if (OperationPCI.ReadIDCard(ref IDCardInfo, ref strError))
                        {
                            WinContext.SetData<IDCard_XZX_DKQ116D.IDCardData>("IDCardData", IDCardInfo);
                            return true;
                        }
                        else
                        {
                            // Common.CommWindow.ShowDialogTip("错误信息", strError, true);
                        }
                        break;
                    case CardTypeMode.BankCard://刷签约银行卡
    
                        string bdCardNo = OperationPCI.ReadMagneticCard();
                        if (bdCardNo != "")
                        {
                            cardInfo.CardNum = bdCardNo;
                            cardInfo.CardType = Oland.HIP.Common.Enums.CardTypeMode.BankCard;
                            string
                                result = GetPatientInfoAndSave(cardInfo);
    
                            if (result == "")
                                return true;
                            else
                            {
                                Common.CommWindow.ShowDialogTip("", result, false);
                                HSS.Common.OperationPCI.BackCard();
                                return false;
                            }
                        }
                        break;
                    case CardTypeMode.MedicalCard://刷就诊卡
    
                        string mcCardNo = OperationPCI.ReadMagneticCard();
                        if (mcCardNo != "")
                        {
                            cardInfo.CardNum = mcCardNo;
                            cardInfo.CardType = Oland.HIP.Common.Enums.CardTypeMode.MedicalCard;
    
                            string result = GetPatientInfoAndSave(cardInfo);
    
                            if (result == "")
                                return true;
                            else
                            {
                                Common.CommWindow.ShowDialogTip("", result, false);
                                HSS.Common.OperationPCI.BackCard();
                                return false;
                            }
                        }
                        break;
                    default:
                        break;
                }
                return false;
            }
    
            //错误信息
            static ErrorMessageInfo errInfo;
    
            /// <summary>
            /// 根据卡号获取病人信息并存储
            /// </summary>
            /// <param name="cardInfo">卡信息</param>
            /// <param name="isReg">是否为登记,登记从基础服务取数据,其他从住院服务取数据</param>
            /// <returns>成功返回“”</returns>
            public string GetPatientInfoAndSave(CardInfo cardInfo)
            {
                string error = "";
                 Common.CommWindow.BeginProgressBar("",0);
                try
                {
                    //根据卡号获取病人信息
    
                    if (myModule == Modules.Register)
                    {
                        PatientInfo patientInfo = HIPServices.BasicServiceClient.GetPatientInfoByCard(out errInfo, cardInfo);
                        if (patientInfo != null)
                        {
                            WinContext.SetData<PatientInfo>("PatientInfo", patientInfo);
                        }
                        else
                            error =cardInfo.CardType==CardTypeMode.BankCard? "非签约银行卡,请更换就银行卡重试":"非本院就诊卡,请更换后重试";
                    }
                    else
                    {
                        InHospitalPatientInfo patientInfo = HIPServices.InHospitalServiceClient.GetHospitalPatientInfoByCard(out errInfo, cardInfo);
                        if (patientInfo != null)
                        {
                            WinContext.SetData<InHospitalPatientInfo>("InHospitalPatientInfo", patientInfo);
                        }
                        else
                        {
                            error = cardInfo.CardType == CardTypeMode.BankCard ? "非签约银行卡,请更换就银行卡重试" : "非本院就诊卡,请更换后重试";
                        }
                    }
                }
                catch (Exception ex)
                {
                    error = "连接服务失败,请到其它自助设备或窗口办理";
                }
                Common.CommWindow.EndProgressBar();
                return error;
            }
        }
    

    代码凌乱,层次不清晰,过多的判断,扩展性差.....真的快看不下去了.所以决定重构下.因为最近在学设计模式,仔细分析下,这不正好策略模式很像吗?

    先看下策略模式的组成:

      

    抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
    具体策略角色:包装了相关的算法和行为。
    环境角色:持有一个策略类的引用,最终给客户端调用。
     
    再看下策略模式的定义:
     
      策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。
     
    好,我们对策略模式稍微有了了解,那我们开始重构这段代码:
    首先讲下这段代码要实现的功能,他主要是刷卡功能的实现,有就诊卡,银行卡,医保卡等,每种卡对应不同的刷卡器,同时对应不同的信息提示与背景显示等.
    我们先定义一个刷卡接口,将需要改变的信息都给抽象出来.
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Oland.HIP.Common.Enums;
    using Oland.HIP.Common.Entities;
    namespace Oland.HSS.InHospital.SwipingCard
    {
        public interface ISwipingCard
        {
    
            /// <summary>
            /// 卡名称
            /// </summary>
             string CardName { get; }
    
            /// <summary>
            /// 卡类型
            /// </summary>
            CardTypeMode CardType { get; }
            /// <summary>
            /// 界面信息提示
            /// </summary>
            string TipMsg { get; }
    
            /// <summary>
            /// 背景图片路径
            /// </summary>
            string BackgroundImagePath { get; }
    
            /// <summary>
            /// 检测硬设
            /// </summary>
            /// <returns></returns>
            bool CheckDevice();
    
            /// <summary>
            /// 播放语音提示
            /// </summary>
            void PlayVoice();
    
            /// <summary>
            /// 刷卡
            /// </summary>
            /// <returns></returns>
            CardInfo SwipingCard();
    
            /// <summary>
            /// 将数据存储到缓存
            /// </summary>
            /// <returns></returns>
            string SaveData();
        }
    }

    下面分别是各个具体的刷卡类型

    银行卡:

    class SwipingBankCard : ISwipingCard
    {}

    就诊卡:

    class SwipingMedicalCard:ISwipingCard
    {

    }

    等等^........

    下面是文件结构,如果在增加相应的类就行了

    下面咱们再把最上面的代码再看下:

      public class BaseSwingCardWindow : BaseWindow
        {
            //检测读卡器是否打开 
            public bool IsOpened { get; set; }
    
            //刷卡的模块
            public Modules myModule { get; set; }
    
            //刷卡定时器
            DispatcherTimer SwingTimer;
    
            public BitmapImage bgImg;
            //切换提示信息
            public string tipMsg = "请按提示刷您的签约
    银行卡";
            public BaseSwingCardWindow() { }
            public BaseSwingCardWindow(ISwipingCard swipingCard)
            {
                Common.CommWindow.BeginProgressBar("", 1000);
    
                bgImg = new BitmapImage(new Uri(swipingCard.BackgroundImagePath, UriKind.Relative));
                tipMsg = swipingCard.TipMsg;
    
                //Load事件播放语音
                this.Loaded += (s, e) => swipingCard.PlayVoice();
                //窗口关闭,停止定时器
                this.Closed += (s, e) => this.SwingTimer.IsEnabled = false;
    
                //创建定时器间隔读取卡号
                CreateDispatcherTimer(swipingCard);
    
                string strError;
                //检测读卡器
                if (swipingCard.CheckDevice())
                {
                    if (HSS.Common.OperationPCI.CheckDevice(out strError, DeviceName.Printer))
                    {
                        IsOpened = true;
                        SwingTimer.IsEnabled = true;
                    }
                    else
                    {
                        IsOpened = false;
    
                        Common.CommWindow.ShowDialogTip("", "小票打印机故障,请联系柜台!");
                    }
                }
                else
                {
                    IsOpened = false;
                    Common.CommWindow.ShowDialogTip("", string.Format("{0}故障,请联系柜台!", swipingCard.CardName));
                }
                Common.CommWindow.EndProgressBar();
            }
    
            private void CreateDispatcherTimer(ISwipingCard swipingCard)
            {
                SwingTimer = new DispatcherTimer();
                SwingTimer.Interval = TimeSpan.FromSeconds(1);
                SwingTimer.Tick += (s, e) =>
                {
                    CardInfo cardInfo = swipingCard.SwipingCard();
                    if (!string.IsNullOrEmpty(cardInfo.CardNum))
                    {
                        SwingTimer.IsEnabled = false;
    
                        string msg = GetPatientInfoAndSave(cardInfo);
                        if (msg != "")
                        {
                            Common.CommWindow.ShowDialogTip("", msg);
                            HSS.Common.OperationPCI.BackCard();
                        }
                        else
                        {
                            SwingTimer.IsEnabled = false;
                            TransWin();
                        }
                    }
                };
            }
    
            //用于基类重写,实现刷卡后跳转功能
            public virtual void TransWin()
            {
            }
    
            //错误信息
            static ErrorMessageInfo errInfo;
    
            /// <summary>
            /// 根据卡号获取病人信息并存储
            /// </summary>
            /// <param name="cardInfo">卡信息</param>
            /// <param name="isReg">是否为登记,登记从基础服务取数据,其他从住院服务取数据</param>
            /// <returns>成功返回“”</returns>
            public string GetPatientInfoAndSave(CardInfo cardInfo)
            {
                //刷身份证不需要从数据库读取数据
                if (cardInfo.CardType == CardTypeMode.IDCard)
                {
                    return"";
                }
                string error = "";
                Common.CommWindow.BeginProgressBar("", 0);
                try
                {
                    //根据卡号获取病人信息
    
                    if (myModule == Modules.Register)
                    {
                        PatientInfo patientInfo = HIPServices.BasicServiceClient.GetPatientInfoByCard(out errInfo, cardInfo);
                        if (patientInfo != null)
                        {
                            WinContext.SetData<PatientInfo>("PatientInfo", patientInfo);
                        }
                        else
                            error = cardInfo.CardType == CardTypeMode.BankCard ? "非签约银行卡,请更换就银行卡重试" : "非本院就诊卡,请更换后重试";
                    }
                    else
                    {
                        InHospitalPatientInfo patientInfo = HIPServices.InHospitalServiceClient.GetHospitalPatientInfoByCard(out errInfo, cardInfo);
                        if (patientInfo != null)
                        {
                            WinContext.SetData<InHospitalPatientInfo>("InHospitalPatientInfo", patientInfo);
                        }
                        else
                        {
                            error = cardInfo.CardType == CardTypeMode.BankCard ? "非签约银行卡,请更换就银行卡重试" : "非本院就诊卡,请更换后重试";
                        }
                    }
                }
                catch (Exception ex)
                {
                    error = "连接服务失败,请到其它自助设备或窗口办理";
                }
                Common.CommWindow.EndProgressBar();
                return error;
            }
        }

    重构后代码量减少了将近一半以上,而且更容易扩展了,可读性也高了许多^,另外这里的我将接口在构造函数中使用,而更常用的方式是把ISwipingCard设为属性

    怎样调用:

      SwipingCard.SwipingBankCard sbc = new SwipingCard.SwipingBankCard();
                WinQuerySwingCard winSwing = new WinQuerySwingCard(sbc);
                if (winSwing.IsOpened)
                {
                    winSwing.myModule = Modules.Print;
                    winSwing.Show();
    
                    this.Close();
                }
                else
                {
                    winSwing.Close();
                }
    Ps:这里WinQuerySwingCard 继承自BaseSwingCardWindow
  • 相关阅读:
    Maven 集成Tomcat插件
    dubbo 序列化 问题 属性值 丢失 ArrayList 解决
    docker 中安装 FastDFS 总结
    docker 从容器中拷文件到宿主机器中
    db2 相关命令
    Webphere WAS 启动
    CKEDITOR 4.6.X 版本 插件 弹出对话框 Dialog中 表格 Table 自定义样式Style 问题
    SpringMVC JSONP JSON支持
    CKEDITOR 3.4.2中 按钮事件中 动态改变图标和title 获取按钮
    git回退到远程某个版本
  • 原文地址:https://www.cnblogs.com/smiler/p/3293369.html
Copyright © 2011-2022 走看看