使用Dictionary泛型集合封装业务逻辑判断 z
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的更多相关文章
- C#中Dictionary泛型集合7种常见的用法
要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) Dictionary的描述1.从一组键(Key)到一组值( ...
- c#利用泛型集合,为自己偷偷懒。
有人说"越懒"的程序员进步的越快!其实还挺有道理.亲身体验,从刚出来工作到现在,自己变"懒"了许多,但感觉写出来的代码确有了不少提升.刚开始啊,同样的代码,赋值 ...
- C#中的泛型和泛型集合
泛型 泛型引入了一个概念:类型参数.通过使用类型参数(T)减少了运行时强制转换或装箱操作的风险,通过泛型可以最大限度的重用代码,保护类型的安全及提高性能,他的最常见应用就是创建集合类,可以约束集合类中 ...
- C#泛型集合之Dictionary<k, v>使用技巧
1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...
- C#基础精华03(常用类库StringBuilder,List<T>泛型集合,Dictionary<K , V> 键值对集合,装箱拆箱)
常用类库StringBuilder StringBuilder高效的字符串操作 当大量进行字符串操作的时候,比如,很多次的字符串的拼接操作. String 对象是不可变的. 每次使用 System. ...
- C#泛型集合—Dictionary<K,V>使用技巧
转载:http://blog.csdn.net/a125138/article/details/7742022 1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collec ...
- 泛型集合List<T> Dictionary<K,V>
List<T>类似于ArrayList,ArrayList的升级版. 各种方法:Sort().Max().Min().Sum()… Dictionary<K,V>类似于Ha ...
- 转载C#泛型集合—Dictionary<K,V>使用技巧
1.要使用Dictionary集合,需要导入C#泛型命名空间 System.Collections.Generic(程序集:mscorlib) 2.描述 1).从一组键(Key)到一组值(Value) ...
- 计算字符串中每种字符出现的次数[Dictionary<char,int>泛型集合用法]
有一道经典的面试题: 统计 welcome to china中每个字符出现的次数,不考虑大小写. 第一个出现在脑海里的想法是: 1. 将字字符串转换成 char数组: 2. 用 for循环遍 ...
随机推荐
- HTML小工具
一般可能用的到的符号代码: 符号 HTML 符号 HTML & & < < > > ⁄ ⁄ " " ¸ ¸ ° ° ½ ½ ¼ ¼ ...
- 【LOJ】#2447. 「NOI2011」兔兔与蛋蛋的游戏
题解 对于75分来说,操作肯定不会成环,可以暴搜 看成空格在移动,空格移动到原来的位置肯定经历了偶数个格子,但是操作的人是两个不同的人,所以肯定不会成环 对于满分做法,要找到一种更好的方式判先手是否会 ...
- HDU - 5136 2014icpc南京现场赛J 计数dp
题目大意:给你一个树的直径k,要求每个点的度数不超过3, 问你有多少棵树满足条件. 思路:好难啊. 主要思想就是将一棵无根二叉树树划分成有根二叉树. 我们对k的分奇偶讨论: 我们定义dp[ i ] 为 ...
- Django实战(14):让页面联动起来
上一节我们实现了一个”能看不能用“的购物车,现在我们来使用这个购物车. 首先是产品目录界面中的”加入购物车“链接,我们希望点击这个按钮后,在购物车中添加该产品(添加的规则是如果购物车中已经有该产品就增 ...
- Gitlab-通过API管理项目
Gitlab有一个非常强大的API,几乎可以通过API管理在Gitlab服务器中的所有项目. 在这里我们只是测试终端点的API, 因此我们需要一个程序来进行测试 .在这里我使用的是针对Google浏览 ...
- 查看当前session权限
oracle 1111.2.0.1.0 环境 查看connect都有什么权限 SQL> select * from dba_sys_privs where GRANTEE='CONNECT'; ...
- pandas使用总结
一.pandas简介 Pandas是基于Numpy开发出的,是一款开放源码的BSD许可的Python库,为Python编程语言提供了高性能,易于使用的数据结构和数据分析工具.Pandas用于广泛的领域 ...
- linux下解除端口占用
1.找出占用端口进程的pid sudo lsof -i:port 2.终止进程 pid
- R语言实战(十)处理缺失数据的高级方法
本文对应<R语言实战>第15章:处理缺失数据的高级方法 本文仅在书的基础上进行简单阐述,更加详细的缺失数据问题研究将会单独写一篇文章. 处理缺失值的一般步骤: 识别缺失数据: 检查导致数据 ...
- 设置 cookie过期时间
cookie.setMaxAge(0);//不记录cookie cookie.setMaxAge(-1);//会话级cookie,关闭浏览器失效 cookie.setMaxAge(60*60);//过 ...