最近刚刚入职,一个高级程序员要求我改进一个switch case的代码,这段代码其实也是我写的,但是他在review的时候思来想去还是想让我用lambda功能来简化代码.
所以我是得到一个XmlObject,这个object含有在数据库中提取出来的xml文件中的不同根元素的信息,我们的需求是运行命令来将这个生产代码的xml数据来进行匿名化处理,然后让开发人员们用匿名数据进行开发而不是生产数据从而保证数据的安全。(请专注于需求,我知道这很刁钻,但是我们公司的软件真的是太老了。16年前开始开发,整个乙方现在就一个人在维护,我们作为甲方雇的两个初级程序员正在每天啃生肉,遇到问题就扔给我们,也没时间说这代码以前都经历了什么。真的是名副其实的屎山。)
这个XmlObjectNodeNames是一个enum类型的class,只是觉得手动输入string真的很不美观,所以就用这种方式来统一下代码。而后面的就是enum里面的元素,就是xml文件中所有我们需要匿名的元素名称,也就是说上一层代码会遍历xml的根元素,只要遍历到这些元素,就会返回一个相应的功能,这个功能就是用NuGet里面的faker来随机生成一个比较合理的虚假值,然后往下一层就是用虚假的值代替生产值,从而达到匿名化的结果。
private void AnonymizeXml(MatisseXmlObject xmlObject)
{
//简化一下只写片段
switch (element.Name)
{
case "Name": //这里的Name就对应了下面的XmlObjectNodeNames.Name
AnonymizeXmlProperty(XmlObjectNodeNames.Name, xmlObject);
break;
case...//以此类推
}
private void AnonymizeXmlProperty(XmlObjectNodeNames dataTypeForAnonymize, MatisseXmlObject xmlObject)
{
//主要代码,取代生产代码
fakeValue = GenerateFakeValue(dataTypeForAnonymize);
}
public string GenerateFakeValue(XmlObjectNodeNames targetFakeData)
{
switch (targetFakeData)
{
case XmlObjectNodeNames.Name:
case XmlObjectNodeNames.AgentName:
case XmlObjectNodeNames.CustomerName:
case XmlObjectNodeNames.SolicitorName:
return FakePersonName();
case XmlObjectNodeNames.Address:
case XmlObjectNodeNames.StreetAddress:
case XmlObjectNodeNames.Destination:
return FakeAustralianAddress();
case XmlObjectNodeNames.SessionID:
case XmlObjectNodeNames.InvoiceNumber:
return FakeUniqueReadableSerialNumber();
case XmlObjectNodeNames.StreetName:
return FakeStreetAddress();
case XmlObjectNodeNames.ReceiptEmail:
case XmlObjectNodeNames.Email:
case XmlObjectNodeNames.EmailAddress:
case XmlObjectNodeNames.SentAddresses:
return FakeEmailAddress();
case XmlObjectNodeNames.PhoneNumber:
case XmlObjectNodeNames.LocalNumber:
return FakePhoneNumber();
case XmlObjectNodeNames.ContractNumber:
return FakeContractNumber();
case XmlObjectNodeNames.RegistrationNumber:
return FakeCarRegistration();
case XmlObjectNodeNames.JobNumber:
case XmlObjectNodeNames.Bsb:
case XmlObjectNodeNames.BSBNumber:
case XmlObjectNodeNames.Value:
case XmlObjectNodeNames.BpayBillerCode:
return GetNumbers(6);
case XmlObjectNodeNames.ABN:
case XmlObjectNodeNames.ACN:
case XmlObjectNodeNames.AccountNumber:
case XmlObjectNodeNames.LicenseNumber:
case XmlObjectNodeNames.CustomerAccountNumber:
return FakeAccountNumber();
case XmlObjectNodeNames.CustomerNumber:
return FakeCustomerNumber();
case XmlObjectNodeNames.FileName:
return FakeFileName();
case XmlObjectNodeNames.ReferenceNumber:
case XmlObjectNodeNames.InsightRefNumber:
case XmlObjectNodeNames.PolicyNumber:
return FakeReferenceNumber();
case XmlObjectNodeNames.IpAddress:
return FakeIpAddress();
default:
return String.Empty;
}
}
现在就是想用lambda(上面给的要求,我是真查不到,也没学)来取代上面的代码,但是随着数据库可能继续扩展的情况下,switch case也是会无休止的长,这时候是真的需要一个lambda来进行优化。但是我们用的数据库也是老掉牙了,所以想改变现状也是不太可能,只能按需求更新代码,上面给了一个词交,代码即数据,我网上查了一下,懂得原理,但是让我把“代码即数据”,lambda当在一起来取代switch case。我是琢磨到升天估计也弄不明白。
这跟lambda有什么关系
实际就是你们把应该在数据库里做关联的东西写死在代码里了
在数据库里建个表,一个字段是targetFakeData,一个字段是function,把你所有的case写在targetFakeData字段里,把要执行的函数名写在function里,然后根据数据库返回的函数名直接反射调用函数