我开始从一个项目中提取数据并将其写回旧系统数据库。我已经开始使用域模型,并试图在过去的系统中改进这种设计,所以我想对此进行一些反馈。
这个例子是任意的,所以不需要那里的具体建议,但是假设数据库中有一个名为“WorkflowStep”的表,我正在编写一个类。表中有一个名为“CurrentStatus”的列定义了工作流的状态。它存储为varchar。此列的整个表格中有五个不同的字符串,并且不太可能被更改...值如“打开”,“已关闭”,“暂停”等等。
该类需要跟踪此值,但以何种方式?我可以走简单的路线,只是将它存储在一个字符串中,但这个定义不是很明确,我想设想未来的开发人员寻找字符串的不同值来应用逻辑。我可以使用枚举来使事情更明确,但这可能导致切换/案件地狱到处都是。我已经阅读了工程师创建界面的方法,比如说“IStatus”,然后制作代表状态的每个可能状态的具体类,但是在与此情况相同的情况下的其他一些列可能有一百个不同的值,所以100每个州的课程都有点矫枉过正。
我的主要问题:一种方法事实上比其他方法更好,如果没有,我应该考虑选择一种方法?
请注意,该项目仍处于起步阶段,我不确定该类的“status”属性将如何使用。它可能是无用的,或者它可能证明是至关重要的:我还不确定。
答案 0 :(得分:2)
我个人更喜欢这种转换语句
var x = new Dictionary<Status, Action>
{Status.Fail, ()=>Console.Writeline("Fail")}
{Status.Ok, ()=>Console.Writeline("Ok")};
x[Status.Fail]();
x[Status.Ok]();
另外 - 你可能会喜欢Jimmy this article(如果你坚持使用枚举方案)。
答案 1 :(得分:2)
我不认为这方面有任何明确的答案,但这是一个常见的问题,以下方法一直很适合我:
对于像CurrentStatus这样的东西,它听起来像选项2或3将是自然的契合。如果以下任何一种情况适用,则备选方案3将是更可取的:
答案 2 :(得分:1)
我已经阅读了工程师创建界面的方法,比如说“IStatus”,然后制作代表状态的每种可能状态的具体类,
那将是State Pattern。
但是与此相同情况下的其他一些列可能有一百个不同的值,因此每个州的100个类似乎有点过分。
这似乎是一个单独的问题。没有更多细节,没有太多可说的。
答案 3 :(得分:1)
我建议您研究域驱动设计中定义的“值类型”的概念。这个WorkflowStep的东西听起来像是一个主要的候选人。你没有提到你编写的语言或环境,但是在.Net中,如果我最终使用这个概念,我会创建一个表示这个对象的结构,并编码,以便在它的公共接口中使用,客户端代码贯穿系统的其余部分,它出现在enum中,并将用作枚举。
MyTask.WorkFlowStatus = WorkFlowStep.OnHold;
// creates and assigns new instance of struct
在C#中
public struct WorkflowStep
{
public static readonly WorkflowStep Null = new WorkflowStep();
public static readonly WorkflowStep Open = new WorkflowStep(1);
public static readonly WorkflowStep Closed = new WorkflowStep(2);
public static readonly WorkflowStep OnHold = new WorkflowStep(3);
private int val;
private bool def;
public bool HasValue { get { return def; } }
public bool IsNull { get { return !def ; } }
private WorkflowStep ( ) { } // disable public instantiation
private WorkflowStep (int value)
{
val = value;
def = true ;
}
}
您可以在模型中输入需要跟踪此WorkflowStep
的其他clases的属性。此结构的每个实例的内存占用量非常小,用于保存值的int和用于保持其可空状态的bool。您可以为结构添加其他方法和重载,以启用打印格式输出,ToString Overloads,无论您想要什么......
答案 4 :(得分:1)
这是一个非常常见的问题,很大程度上取决于对问题的理解。通常我认为这是简单性,可读性和可扩展性之间的交集。
最简单=枚举。最可读=字符串。最可扩展=参考表。
哪一个最适合您的问题?
答案 5 :(得分:1)
如果您非常确定状态的选项数量不会增加,则枚举将起作用。我认为你可以通过一些精心设计来避免切换/案例问题...也许使用策略模式。
另一方面,如果选项的数量可能会增加,那么创建一个WorkFlowStatus类将是最佳选择。这将允许您在不修改代码的情况下添加更多状态。我不认为你必须为每个人的状态创建一个班级。
答案 6 :(得分:1)
通常,您最终会将此类型的项目作为枚举引用。如果你想避免切换/案例地狱,你可以使用映射到每个枚举的Action - 这是一个例子:
private Dictionary<WorkflowStep, Action> _actions =
new Dictionary<WorkflowStep, Action>();
然后用
分配_actions.Add(WorkflowStep.Open, OpenCommand);
_actions.Add(WorkflowStep.Closed, ClosedCommand);
你会有这样简单的方法:
private void OpenCommand()
{
// Do something
}
private void ClosedCommand()
{
// Do something.
}
最后,要调用它,你可以:
if (_actions[step] != null)
{
_actions[step]();
}
请注意,您可以使用字符串执行此操作 - 不使用枚举,但此方法可帮助您避免代码中的魔术字符串。
答案 7 :(得分:1)
state-pattern听起来合理。
如果您有更多不同的值,您可以使用其中一个根实现,并添加一些 decorator-pattern