背景:1.每次扫描一个产品上的标签,然后放入包装箱,扫描次数达到产品包装数后触发外箱打印
2.当剩余产品不够包装数时,用户可点击按钮完成尾箱标签打印
3.禁止不同料号的产品混放在同一个包装箱里
4.禁止两个批次的产品混放在同一个包装箱里
分析:
1.根据上面的业务分析,我们先建产品类Sheet,再建包装箱类Carton;Carton类即包含属性也包含方法,属性反应了对象的状态,如这项产品的批次、生产日期、数量等,方法是对象的某种行为能力,这里我们说包装箱具备存放产品的能力。下面用了AcceptSheet方法来表述这个行为(之前想过用Receive,Put之类的单词,但还是觉得Accept更准确些)。AcceptSheet(sheet)表示实际当中员工往箱子里放了一片产品
2.产品混放和混合批次装箱我把它们当作是装箱的结果,且用CartonState枚举来标识这个状态,AcceptSheet方法的返回结果值中包含了CartonState枚举,正常情况下装箱返回CartonState.Accepted,表示箱体已“接受”这片产品。
public DtoPackageResult AcceptSheet(Sheet sheet)//装箱
{
//装箱状态,比如1/5表示箱子可以放5片产品,当前已装了一片产品
DtoPackageResult cartonPackageResult = new DtoPackageResult
{
State = CartonState.Accepted,//箱体状态枚举
CartonProgressDescription = “1/5”
};
_Sheets.Add(Sheet);
return cartonPackageResult;
}
3.箱体都有“存放”的能力,但存在哪?所以在Carton类中设置了一个私有属性_sheets,用来存放产品
private readonly List<DtoSheet> _sheets;//箱内数据
4.有了_sheets的存在判断什么是混批将变得如此简单,
public bool IsDuplicationBatch(string batchno)
{
return _sheets.Count != 0 && _sheets.Any(x => x.BatchNo != batchno);
}
5.调用出代码如下:
var packageResult = _outerCarton.AcceptSheet(dtoSheet5);
switch (packageResult.State)
{
case CartonState.SheetDuplicationError:
{
//("重复扫描!");
}
break;
case CartonState.SheetMergeBatchError:
{
//("混批异常!");
}
break;
case CartonState.Accepted:
{
}
break;
}
用winform c#程序实现如下 :
//简化后的产品类
public class Sheet
{
public int SheetId { get; set; }
public string BatchNo { get; set; }
public string FullNum { get; set; }
public decimal Quantity { get; set; }
}
public class Carton
{
public decimal _capcity;//容积=包装数量*系数
private readonly List<Sheet> _sheets;//箱内数据
public Carton(decimal capcity)
{
_capcity = capcity;
_Sheets= new List<Sheet>();
}
public bool IsTail//是否尾箱
{
get { return _sheets.Sum(x => x.Quantity) != _capcity; }
}
public decimal TotalQuantity//箱内当前数量合计
{
get { return _Sheets.Sum(x => x.Quantity); }
}
public string BatchNo//批次
{
get{return _Sheets.First().BatchNo;}
}
public bool IsFull//箱体是否已装满
{
get
{
return _Sheets.Sum(x => x.Quantity) == _capcity;
}
}
public bool IsDuplicationBatch(string batchno)//是否混批
{
return _sheets.Count != 0 && _sheets.Any(x => x.BatchNo != batchno);
}
public DtoPackageResult AcceptSheet(Sheet sheet)//装箱
{
//返回外部调用处当前装箱状态,比如1/5表示已装了一片产品
DtoPackageResult cartonPackageResult = new DtoPackageResult
{
State = CartonState.Accepted,//箱体状态枚举
PackCapcity = 0,
AcceptedCapcity = 0,
CartonProgressDescription = string.Empty,
OuterCartonProgressDescription = string.Empty
};
_Sheets.Add(sheet);
return cartonPackageResult;
}
}
public enum CartonState
{
[Description("重复装箱")] SheetDuplicationError,
[Description("混批装箱")] SheetMergeBatchError,
[Description("装箱中")] Accepted,
[Description("已满")] Full,
[Description("溢出")] Overflow
}
后续我将已上面这个场景为例子,来介绍我对领域驱动设计在生产线标签打印方面的应用看法,欢迎大伙儿拍砖