C# 一种适用于条件模型中大型条件的设计模式
我正在重写一个野兽般的程序,它无所不能,而且是厨房水槽。这是一个电话IVR系统(按1到布拉,按2到…)我已经将它的所有功能划分到了自己的项目中,但是我最大的一个痛点是当我们第一次接听电话时,让用户输入一个代码,让我们知道将呼叫发送到哪个系统 整个代码系统乱七八糟,但无法更改,我已将大约800行VB6重构为类似以下代码的内容:C# 一种适用于条件模型中大型条件的设计模式,c#,design-patterns,C#,Design Patterns,我正在重写一个野兽般的程序,它无所不能,而且是厨房水槽。这是一个电话IVR系统(按1到布拉,按2到…)我已经将它的所有功能划分到了自己的项目中,但是我最大的一个痛点是当我们第一次接听电话时,让用户输入一个代码,让我们知道将呼叫发送到哪个系统 整个代码系统乱七八糟,但无法更改,我已将大约800行VB6重构为类似以下代码的内容: string code = foo.GetAccessCodeFromCaller(); if (DatabaseCheck1(code) { parse = Pa
string code = foo.GetAccessCodeFromCaller();
if (DatabaseCheck1(code)
{
parse = ParseCode(code);
dbValue = GetSomethingFromDB(parse);
if (OtherCheck1(dbValue)
{
// Launch the Pay Taxes project.
}
else if (OtherCheck2(dbValue)
{
// Launch the Uploaded File project
}
else
{
// Schedule Something or other project
}
}
else if (LookForSomethingElseInDB(code)
{
parse2 = AltParseMethod(code)
if (Conditional(parse2))
{
if (LargeChunkOfCodeConditional(code))
{
// Report a something or other project.
}
else
{
// Talk to Tech Support.
}
}
else
{
// Invalid Input
}
}
else
{
if (YetAnotherChunkOfCode(code))
{
// Order products project
}
else
{
// Invalid Input.
}
}
我需要一个好的体系结构来正确地完成这个系统,正确的体系结构等同于具有高度的适应性,可以让更多的垃圾鞋进入它。最初的系统是在VB4/5中完成的,经过了16年的近月变化。我想要的东西能让这乱七八糟的局面保持有序,并且在接下来的16年里很容易添加垃圾
到目前为止,我已经尝试了一些模式(Visitor和Command),但似乎没有什么适合我尝试实现它的方式。如果您有任何建议,我们将不胜感激
编辑:
更清楚一点,我当前的体系结构有以下项目的解决方案:Dispatch、Paytax、UploadedFiles、ScheduleSomething、ReportSomething、TechSupportRedirect、OrderProducts等。。。(以及硬件应用、共享接口和数据库访问项目)。Dispatch使用HardwareAbstraction项目接听电话并询问呼叫者代码,然后将呼叫路由到其他10个执行完全不同任务的项目中的一个(然后可以由10个不同的开发人员并行重写,而不会被踩到)
我可以很好地理解目标项目的体系结构,但是实际的调度项目让我很困惑。另外,如果我的整个解决方案体系结构是某种反模式的,有人会在我走得太远之前告诉我。也许你需要的只是一个简单的提取方法,将大量内部条件排除到单独的方法。我对VB6一无所知,但是如何将代码映射到“委托”呢(不知道VB6中是否存在这个概念)。其思想是:输入代码是返回要调用的方法的字典的“键”(如果找不到这样的代码,则为空/空/无) 更新: 如果这是用C#写的,你就不能把代码放到
Dictionary<string, Action> OpCodes;
更新2:
似乎你有“层”的条件。我想这会映射到“字典中的字典”。但考虑到这个问题:用户键入一系列选择,这些选择应该以某种行为结束,听起来像:为每个系统行为定义“委托”,并映射到代码:
比如:
如果您重写它以创建不同的类来处理不同的代码,那么可能会使您的代码库更易于维护 差不多
var codeHandler = CodeHandlerDecider.GetCodeHandlerFor(
foo.GetAccessCodeFromCaller());
codeHandler.HandleCode();
然后,您的CodeHandlerDecider将执行以下操作:
public static ICodeHandler GetCodeHandlerFor(string code)
{
if (DatabaseCheck1(code)
{
return new FirstCodeHandlerClass(code);
}
else if (LookForSomethingElseInDB(code)
{
return new SecondCodeHandlerClass(code);
}
else
{
return new ThirdCodeHandlerClass(code);
}
}
然后一个示例类是
public class FirstCodeHandlerClass: ICodeHandler
{
public void HandleCode(string code)
{
parse = ParseCode(code);
dbValue = GetSomethingFromDB(parse);
if (OtherCheck1(dbValue)
{
// Launch the Pay Taxes project.
}
else if (OtherCheck2(dbValue)
{
// Launch the Uploaded File project
}
else
{
// Schedule Something or other project
}
}
}
界面看起来像
public interface ICodeHandler
{
void HandleCode();
}
这听起来像是一项工作!你甚至可以想象并创建一个外部DSL,因为状态机非常适合于此。事实上,我刚刚发现它似乎使用电话系统作为其主要示例。这类问题有两种常见模式: 1) 子类化/继承以实现多态调度 2) 表驱动编程 基本思想是将允许您做出决策的信息放在表中,然后编写遍历表的代码。如果你从一个有趣的角度思考,多态方法就是直接构建到语言中的表驱动编程。表驱动技术为您提供了以下好处:更具声明性、更小的代码大小、易于扩展/添加新案例、更清晰
正如其他人所指出的,您可以使用字典来实现此模式。多亏了这里的所有人,由于这些建议,我克服了一些心理障碍,发现责任链模式将很好地解决我的问题。我正在用C#重写整个项目,因为管理层决定购买的硬件有一个非常干净的.net API。考虑一下:代码1002*34567是我们的一种格式。为了处理它,我们在*(客户概要1002)之前查找客户概要。如果该配置文件存在,那么什么操作与34567匹配。基本上,将所有可能的代码组合存储在字典中是困难的,而且它会不断变化。比如说有人上传了一个文件,文件被拒绝了,两分钟后,他们打电话给客户服务部,告诉他们拒绝访问代码,我明白你的意思。当用户插入数字时,“做什么”似乎是唯一确定的。如“按2键进行客户服务…输入拒绝访问代码”。。。这就是我用“层”暗示的。让第一个数字映射到字典,直到您唯一地确定了要做什么(调用什么委托)。@Yogin,听起来像是“代码”是用户按下的菜单选项,但现在似乎代码是各种输入的组合,包括用户对提示的响应(例如,“输入您的信用卡号”)。对吗?
public class FirstCodeHandlerClass: ICodeHandler
{
public void HandleCode(string code)
{
parse = ParseCode(code);
dbValue = GetSomethingFromDB(parse);
if (OtherCheck1(dbValue)
{
// Launch the Pay Taxes project.
}
else if (OtherCheck2(dbValue)
{
// Launch the Uploaded File project
}
else
{
// Schedule Something or other project
}
}
}
public interface ICodeHandler
{
void HandleCode();
}