C#封装系列---①多层if..else嵌套的封装改进方法

我们在做项目的时候经常会用到多层的if...else的判断(封装之前的代码):

 private void btnCancelCard_Click(object sender, EventArgs e)
        {
            //1、判断文本框是否为空
            if (txtCancelCardID.Text == "")
            {
                MessageBox.Show("请将信息填写完整");
            }
            else
            {
                List<UserInfo> userlist = userfacade.SelectUser(Convert.ToInt32(txtCancelCardID.Text));
                //2、判断是否有该卡号
                if (userlist.Count > 0)
                {
                    //3、判断是否正在上机
                    if (onlinefacade.SelectOnline(Convert.ToInt32(txtCancelCardID.Text)).Count > 0)
                    {
                        MessageBox.Show("该卡正在上机,请下机后再退卡");
                        txtCancelCardID.Text = "";
                        txtCancelCardID.Focus();
                    }
                    else
                    {
                        cancel.CardID = Convert.ToInt32(txtCancelCardID.Text);
                        cancel.CancelCash = userlist[0].CardCash;
                        cancel.UserName = userlist[0].UserName;
                        cancel.Worker = worker;
                        //4、插入到退卡数据表中
                        if (cancelfacade.InsertCancel(cancel))
                        {
                            //5、将用户从用户表中删除
                            if (userfacade.DeleteUser(cancel.CardID))
                            {
                                txtCancelContext.Text = "账号:" + cancel.CardID + "\r\n" + "姓名:" + userlist[0].UserName + "\r\n" + "退卡金额:" + userlist[0].CardCash + "\r\n" + "操作人员:" + worker.ToString();
                                txtCancelCardID.Text = "";
                                txtCancelCardID.Focus();
                                MessageBox.Show("退卡成功");
                            }
                        }
                        else
                        {
                            MessageBox.Show("下机数据添加失败");
                        }
                    }
                }
                else
                {
                    MessageBox.Show("没有该用户,请核对后再输入");
                    txtCancelCardID.Text = "";
                    txtCancelCardID.Focus();
                }
            }
            
        }

以上代码的五层if...else的嵌套,自己凑着这看没有问题,功能执行也没有问题。那如果我们把整个项目交接出去,当我们给别人说if...else逻辑的时候,我们说的会很清晰,毕竟是自己写的嘛,但对方就是搞不懂,对方的脑子已经被我们说成了浆糊,直接影响了沟通效率。

我们再转换一下角色,试想如果我们是刚刚接手项目的小白,当我们看到上一任的代码是这么多的if..else,心里应该会默默的抱怨一下:这么多嵌套都是干什么的,逻辑好乱啊。当你正在为看代码逻辑而发愁时,负责人过来跟你说,用户改需求了,顿时石化,之后便开始了加班之旅.....

所以,用多层嵌套的if..else不仅仅降低了运行效率,占用了过多的内存,无法满足最基本的开闭原则,而且无论站在哪个角度,都会很尴尬。

那要如何避免用这么多的if...else呢?

这时我们就要站在巨人的肩膀上来解决问题了,设计模式是巨人们留给我们的最好的编写代码的思想,我们可以使用职责链模式来解除if...else间的层层判断,这样即可以达到设计模式中的单一职责原则,开闭原则。我们在交接、修改时都会很方便。

将每一层的if...else判断都设置在一个职责链的类中,功能在不同的类中实现,这样每一个类中的功能都是单一的。

而B层来控制设置以上各个类中的等级,即哪一层先判断,之后再如何逐层运行。上方截图中文件夹中Handler是抽象类,里面设置了抽象的方法供子类来重写,实现子类的多态。这样每层之间的耦合度大大降低,如果用户要改变需求,需要再添加一层判断,那么我们直接在下机职责链(ChainOff)中添加一个类即可。

这时B层代码就是实例化下机职责链(ChainOff)中的不同类,并设置层级关系。

public void Off()
        {
            //创建职责链中的实例
            ChainOff.Handler checkbasic = new CheckBasicHandler();
            ChainOff.Handler checktype = new CheckTypeHandler();
            ChainOff.Handler checkonline = new CheckOnlineHandler();
            ChainOff.Handler insertline = new InsertLineHandler();
            ChainOff.Handler updateuser = new UpdateUserHandler();
            //设置各实例中的上下级关系
            checkbasic.SetSuccessor(checktype);
            checktype.SetSuccessor(checkonline);
            checkonline.SetSuccessor(insertline);
            insertline.SetSuccessor(updateuser);
            //调用第一层的请求方法
            checkbasic.HandleRequest(user); 
        }

下机职责链中的部分代码:

①、抽象类代码:

namespace BLL.ChainOff
{
   public abstract class Handler
    {
        //初始化子类用到的实体,工厂实例以及集合,并将修改符调至为保护型,即只允许子类来访问,这样便达到了很好的复用,不用每个子类都实例化
        protected IDALOnline idalonline;
        protected OnlineFactory onlinefact = new OnlineFactory();
        protected IDALBasicData idalbasic;
        protected BasicDataFactory basicfact = new BasicDataFactory();

        protected Handler successor;  //仅供子类使用的字段
        public void SetSuccessor(Handler successor)//创建设置层级的方法
        {
            this.successor = successor; //将参数赋值给本类中的字段
        }
        public abstract void HandleRequest(UserInfo user);//供子类继承的抽象方法
    }
}

子类代码示例(插入上机记录):

namespace BLL.ChainOff
{
    public class InsertLineHandler:Handler
    {
        public override void HandleRequest(UserInfo user)
        {
            IDALLine idal = linefact.line();  //通过工厂反射实例化上机记录的DAL实例
            if(idal.Insert(online,consumecash)>0)  //对上机记录表中插入信息后的结果进行判断
            {
                successor.HandleRequest(user); //跳至下级
            }
            else
            {
                throw new Exception("上下机数据更新失败");  //异常提示信息
            }
        }
    }
}

通过职责链把if...else解耦只是方法之一,当然还有其他方法,以下是巨人整理的文章:

今日头条

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值