C#2.0 提供了Dictionary 泛型类,它提供了从一组键到一组值的映射。字典中的每个添加项都由一个值及其相关联的键组成。通过键来检索值的速度是非常快的,接近于 O(1),这是因为 Dictionary 类是作为一个哈希表来实现的。本文主要介绍如何通过它来封装一些业务逻辑处理。在客户端可以非常方便的调用。

例子是从我在项目中的一个小的模块重构得来,场景说明:“系统刷单的时候可能要经过很多验证,如操作员权限检查、仓库检查、客户资金检查”等,而且项目中单据类型很多,有发货单、退货单、调拨单等都需要或多或少经过这几步检查,如果不重构的话,将会出现大量的重复代码,而且

逻辑稍微发生修改,对维护也将是一个非常大的噩耗。

客户端代码 ——————>永远不要提供底层不是很关心的数据
客户端只需要这么简单的代码就完成了以前多个if语句的判断,下面是我改善后的代码:
protected override bool HandleRecords(List<ReceiptRecord> res)
{
    if (res.Count <= 0) return false;
    ReceiptRecord record = res[0];
    var productBrand = record.BrandID;
    var branchId = selectBranch1.txtBranchId.Text.Trim();
    var stockId = cmbStockId.SelectedValue.ToString();
    //初始化验证器类(封装的一个底层类型)
    SaoDanValid valid = new SaoDanValid(stockId, productBrand, branchId);
    //添加对仓库的验证
     valid.SetValidObject(new VerifyEntity { VerifyType = SaoDanValidType.Stock, ErrorText = "仓库对应的品牌与扫单所对应的品牌不一致" });
    //添加对操作员的验证
     valid.SetValidObject(new VerifyEntity { VerifyType = SaoDanValidType.User, ErrorText = "没有操作该品牌的权限" });
     //添加对产品的验证
     valid.SetValidObject(new VerifyEntity { VerifyType = SaoDanValidType.Product, ErrorText = "一张单据不能出现多个品牌" });
     //添加对客户资金的验证
     valid.SetValidObject(new VerifyEntity { VerifyType = SaoDanValidType.Customer, ErrorText = "客户没有经营此品牌的权限" });
    //执行逻辑处理
    return valid.Vaild() == true ? true : false;
}
      上面的设计客户端只需要发送必要的数据给底层类型,然后通过枚举指定每个步骤主要是干什么的,具体怎么去做完全是由底层去实现,客户端唯一要做的事情就是传递必要的数据给底层类型,最后每个步骤都添加到Dictionary集合,然后统一调用Vaild方法执行逻辑判断,这样的设计改进,客户端就可以随时随地的添加或删除业务逻辑,同样修改也将十分的方便,从面向对象的的角度去看,更体现了封装的魅力。

业务单元支持的枚举类型
public enum SaoDanValidType
 {
        Stock,       //仓库效验
        User,         //操作员效验
        Customer, //客户效验
        Product     //货品效验
}
      这个枚举就是提供刷单时的效验单元,供客户端使用,当然也可以不用枚举而使用字符串,不过那样不好,因为对系统不是很熟悉的时候很容易写错,
而枚举却似乎带有强硬的选择限制,这样客户端就不会调用出错。

客户端发送数据的类型
public class VerifyEntity
{
        //效验类型
        public SaoDanValidType VerifyType { get; private set; }
        public string ErrorText { get; private set; }
 }
      当然如果这里设计成抽象类型会更好,这样客户端可以对不同的逻辑提供不同的数据。

底层设计
    
/  针对扫单时各单据验证不一致的情况,提取的一个公共类
    ///  主要通过不同的具体类来封装if语句
    public class SaoDanValid
    {
       //提供逻辑封装的一个Dictionary容器, ValidBase表示所有逻辑的抽象基类型
        rivate Dictionary<string, ValidBase> dictionary = new Dictionary<string, ValidBase>();
       // 装客户端对每个逻辑效验时发送的数据,(私有供内部使用)
        ivate List<VerifyEntity> verifyList = new List<VerifyEntity>();
        // 构造器 重载+3
        public SaoDanValid(string productBrand) : this(productBrand, "") { }
        public SaoDanValid(string productBrand, string branchId) : this("", productBrand, branchId) { }
        public SaoDanValid(string stockId, string productBrand, string branchId)
        {
            //初始化Dictionary容器,这里的key和上面的枚举元素对应,value则表示对应要效验的抽象子类
            dictionary.Add("Stock", new StockValid(stockId, productBrand));
            dictionary.Add("User", new UserValid(productBrand));
            dictionary.Add("Customer", new CustomerValid(branchId, productBrand));
            dictionary.Add("Product", new ProductValid(productBrand));
        }
       /提供客户端添加数据
        public void SetValidObject(VerifyEntity obj)
        {
            verifyList.Add(obj);
        }
        //提供客户端效验方法
        public bool Vaild()
        {
            foreach (VerifyEntity entity in verifyList)
            {
                if (dictionary[entity.VerifyType.ToString()].Valid() == false)
                {
                    MessageBox.Show(entity.ErrorText,"提示");
                    return false;
                }
            }
            return true;  //效验通过返回True
        }
    }

效验部分的设计
    public bastract class ValidBase //抽象类
    {
        public abstract bool Valid(); //抽象方法
    }
    public class StockValid : ValidBase
    {
        private string stockID;
        private string productBrand;
        public StockValid(string stockID, string productBrand)
        {
            this.productBrand = productBrand;
            this.stockID = stockID;
        }
        public override bool Valid()
        {
            if (!SaoDanUtil.IsHaveBrandForStock(stockID, productBrand))
            {
                return false;
            }
            return true;
        }
    }
    public class UserValid : ValidBase
    {
        private string productBrand;
        public UserValid(string productBrand)
        {
            this.productBrand = productBrand;
        }
        public override bool Valid()
        {
            //操作员是否有操作该品牌的权限!";
            if (!SaoDanUtil.IsHaveBrandForUser(productBrand))
            {
                return false;
            }
            return true;
        }
    }
    public class CustomerValid : ValidBase
    {
        private string branchId;
        private string currentBrand;
        public CustomerValid(string branchId, string currentBrand)
        {
            this.branchId = branchId;
            this.currentBrand = currentBrand;
        }
        public override bool Valid()
        {
            //客户是否有当前操作品牌的权限
            if (!SaoDanUtil.IsHaveBrandForCustomer(branchId, currentBrand))
            {
                return false;
            }
            return true;
        }
    }
    public class ProductValid : ValidBase
    {
        private string productBrand;
        public ProductValid(string productBrand)
        {
            this.productBrand = productBrand;
        }
        public override bool Valid()
        {
            //一张单据不能出现多个品牌
            return Globals.CurrentUser.CurrentBrand.ToUpper() == productBrand.ToUpper();
        }
    }
}

使用Dictionary泛型集合封装业务逻辑判断 z的更多相关文章

  1. C#中Dictionary泛型集合7种常见的用法

    要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib)  Dictionary的描述1.从一组键(Key)到一组值( ...

  2. c#利用泛型集合,为自己偷偷懒。

    有人说"越懒"的程序员进步的越快!其实还挺有道理.亲身体验,从刚出来工作到现在,自己变"懒"了许多,但感觉写出来的代码确有了不少提升.刚开始啊,同样的代码,赋值 ...

  3. C#中的泛型和泛型集合

    泛型 泛型引入了一个概念:类型参数.通过使用类型参数(T)减少了运行时强制转换或装箱操作的风险,通过泛型可以最大限度的重用代码,保护类型的安全及提高性能,他的最常见应用就是创建集合类,可以约束集合类中 ...

  4. C#泛型集合之Dictionary<k, v>使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  5. C#基础精华03(常用类库StringBuilder,List<T>泛型集合,Dictionary<K , V> 键值对集合,装箱拆箱)

    常用类库StringBuilder StringBuilder高效的字符串操作 当大量进行字符串操作的时候,比如,很多次的字符串的拼接操作. String 对象是不可变的. 每次使用 System. ...

  6. C#泛型集合—Dictionary<K,V>使用技巧

    转载:http://blog.csdn.net/a125138/article/details/7742022 1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collec ...

  7. 泛型集合List<T> Dictionary<K,V>

    List<T>类似于ArrayList,ArrayList的升级版. 各种方法:Sort().Max().Min().Sum()…   Dictionary<K,V>类似于Ha ...

  8. 转载C#泛型集合—Dictionary<K,V>使用技巧

    1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...

  9. 计算字符串中每种字符出现的次数[Dictionary<char,int>泛型集合用法]

    有一道经典的面试题: 统计 welcome to china中每个字符出现的次数,不考虑大小写.      第一个出现在脑海里的想法是: 1. 将字字符串转换成 char数组: 2. 用 for循环遍 ...

随机推荐

  1. MySQL学习笔记:生成时间维度表2

    实现目的: 测试: # 测试 加一秒 SECOND), INTERVAL SECOND); SECOND),'%H%i%s');# 第一秒 SECOND),'%H%i%s');# 最后一秒 SELEC ...

  2. 接口测试工具--Poster与Postman的简单实用

    HTTP/SOAP协议接口的功能测试: 1.浏览器URL(GET请求) http://127.0.0.1:8000/login/?username=zhangsan&password=1234 ...

  3. 20155225 实验四《Android程序设计》实验报告

    20155225 实验四<Android程序设计>实验报告 一.安装Android Stuidio 问题一:安装完成后,打开提示我找不到SDK,我已经设置了环境变量,关掉提示,没有影响. ...

  4. Spring Boot使用JavaMailSender发送邮件

    http://www.cnblogs.com/wxc-xiaohuang/p/9532631.html https://blog.csdn.net/icannotdebug/article/detai ...

  5. android拾遗——Android Intent详解

    一. Intent 作用 Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯.比如说调用startActivity()来 ...

  6. day7 socket网络编程基础

    Socket Socket是什么? 下面来看一下网络的传输过程: 上面图片显示了网络传输的基本过程,传输是通过底层实现的,有很多底层,我们写传输过程的时候,要知道所有的过程那就太复杂了,socket为 ...

  7. Caffe训练AlexNet网络,精度不高或者为0的问题结果

    当我们使用Caffe训练AlexNet网络时,会遇到精度一值在低精度(30%左右)升不上去,或者精度总是为0,如下图所示: 出现这种情况,可以尝试使用以下几个方法解决: 1.数据样本量是否太少,最起码 ...

  8. HDU - 4465 期望 + 取log优化

    思路:这个求期望的公式很容易得到,但是在算的时候我们会遇到一个问题,就是组合数太大了根本存不下, 这时候就可以在计算的时候都取log,最后复原...  以前没遇到过.. #include<bit ...

  9. Hadoop错误1(Text类型与String类型)

    在此类的博客中,博主主要记录的是在Hadoop实践过程中遇到的一些错误,先上一个代码 protected void map(Object key,Text value, Context context ...

  10. 【20181031T2】几串字符【数位DP思想+组合数】

    题面 [错解] 一眼数位DP 设\(f(i,c00,c01,c10,c11)\)-- 神tm DP 哎好像每两位就一定对应c中的一个,那不用记完 所以可以设\(f(i,c00,c01,c10)\)-- ...