现实生活中的程序员应该有多疯狂?
本文关键字:疯狂 程序员 生活 | 更新日期: 2023-09-27 18:17:41
给定:复杂的算法。
switch obj.field1 + "-" + obj.field2
case "A-A":
return Sample(obj){Error = "Type can't be matched"}
case "A-B":
{
if(obj.field3 != null){
var match = otherObjectCollection.FirstOrDefault(otherOb.field2 == obj.field3);
return mathc != null? Sample(obj,match) : Sample(obj){Error="Can't find match"}
}else{use field4...}
}
case "A-C":
{
var related = objectCollection.FirstOrDefault(parent.field4 == obj.field3);
if(related == null)
return Sample(obj){Error = "Can't find parent"}
else {
if(related.field3 != null){
var match = otherObjectCollection.FirstOrDefault(otherOb.field2 == related.field3);
return mathc != null? Samble(obj,match) : Sample(obj){Error="Can't find match"}
}else{ use field 4 ...}
}
}
以此类推。有很多棘手的规则。我想到了下一个决定:
abstract class AggregationChain{
protected MyObj Obj;
abstract string Type{get;}
abstract Priority Priority{get;}
abstract bool Decide(MyObj obj);
abstract Sample Aggregate(ICollection<MyObj> objects,ICollection<OtherObj> otherobjects);
bool CanDecide(MyObj obj){
if(Decide(obj)){
Obj = obj;
return true;
}
return false;
}
}
现在我可以添加ChainLinks例如:
class ABAggregationChainLink{
string Type{get{return "A-B"}}
Priority Priority{get{return Priority.High}}
bool Decide(MyObj obj){
return obj.fiel2 != null;
}
Sample Aggregate(ICollection<MyObj> objects,ICollection<OtherObj> otherobjects){
var match = OtherObjectCollection.FirstOrDefault(otherOb.field2 == obj.field3);
return mathc != null? Samble(obj,match) : Sample(obj){Error="Can't find match"}
}
}
在这个例子中,我需要再创建一个A-B ChainLink来处理"else"的情况。对于所有的开关情况,我需要创建不同的ChainLinks。这当然增加了类的数量和实现的时间,但是类更适合于单元测试,而且在我看来更具可扩展性和灵活性。
问题:
- 我在想——可能是我对Open-Close和"Good"太兴奋了而对于现实生活中的应用来说,最好是创建方法与开关,并照顾可重复使用的零件?
- 在这里填充可能是更好的解决方案?
p。这不是工作的c#代码,我只是试图解释主要的逻辑。
在分析这样的东西时,你不能只看它现在是什么。
- 该算法是否易于维护?
- 多么容易啊在不改变现有功能的情况下添加新规则?
- 多么简单是为了测试吗?
- 你是否需要在运行时添加新规则(插件架构)?
在3种情况下,如果有其他情况,可能无论哪种情况都无关紧要。在40个用例中加上子用例和一个需要单元测试的新需求?我更喜欢每条规则一个类的干净隔离(或者更可能是一个泛型类,将lambda表达式添加到规则集合中)
您的链接类看起来不错,但您仍然需要chain类将所有链接连接在一起,并确定要处理哪个链接。最后可以用一个结构体来代替switch语句,比如:
Dictionary<String, Dictionary<String, List<Link>>> index;
if (index.ContainsKey(obj.Field1))
{
var subIndex = index[obj.Field1];
if (subIndex.ContainsKey(obj.Field2))
{
var linkList = subIndex[obj.Field2];
foreach(var Link in linkList)
{
if (Link.Decide(obj))
{
return Link.Aggregate(objects, otherObjects);
}
}
}
}
如果选择"决定签名"为"Func<bool, MyObj>
和聚合Func<Sample, ICollection<MyObj>,ICollection<OtherObj>>
"
那么你可以添加像
这样的规则RuleChain.AddRule("A", "A", (o) => true, (objs, others) => Sample(obj){Error = "Type can't be matched"})
RuleChain.AddRule("A", "B",...