我想了解如何为班级建模。
该类包含方法A
,B
和C
。这些方法需要按此特定顺序运行,但并非所有方法都是必需的。如果需要,可以拨打A
和B
,而无需致电C
。
这是一个可能的解决方案:
public void RunA()
{
A();
}
public void RunAB()
{
A();
B();
}
public void RunABC()
{
A();
B();
C();
}
但问题是,我需要在运行A
之前处理B
的结果,并在运行B
C
的结果
然后工作流程变为:
A
A
B
B
C
C
我设计上述解决方案的方式,这个工作流程是不可能的。我可以允许A
,B
和C
单独运行,但不再保证操作顺序。
是否有更好的方法来设计此工作流程?
修改
我被问到:
“为什么必须按特定顺序调用这些方法?”
要回答这个问题,我必须解释一下这个问题。 A
,B
和C
,松散地转化为以下步骤:
很明显,A
在链中是第一位的。 B
和C
可能是可以互换的,但是为了这个问题,我们假设C
在B
运行之前没有意义。
A
,B
和C
理论上可以自己处理结果。它主要归结为存储有关结果的信息。但是我想要实现的目标是让班级完全不知道结果的去向。
答案 0 :(得分:0)
我认为你真正要问的问题是“为什么必须以特定的顺序调用这些方法?”。我认为,如果B要求A被召唤,那不是因为“事情原则”。这是因为A完成了B所需的一些工作。如果是这种情况,那么我只需要让A被称为
public void A() { /* Do Work */ }
然后在B方法中,有类似
的东西public void B()
{
if (!CanProcessB()) {
throw new Exception("B is not ready, Call A first");
}
// Do your work here
}
理想情况下,“CanProcessB”私有方法不只是检查A是否被调用。它实际上验证了内部条件是否正确,以便调用B.据推测,A()会在内部设置一些允许调用B的东西。验证该事物并在未准备好时抛出异常。
这是我至少采取的方法。
编辑:
根本问题似乎是你的班级做得太多了。看来这里有三件“事情”。
域到DTO转换
DTO统计学校准
API来电者
老实说,这些似乎是三个不同的职责,如果您正在寻求实施SOLID设计实践,我认为它们应该是三个不同的类。
DomainToDTOConverter
DTOStatisticsCalculator
ApiInterface
DomainToDTOConverter显然接受域对象,并返回DTO。 DTOStatisticsCalculator接受创建的DTO(因此需要调用A),并返回有关它的统计信息。 ApiInterface通过API发送DTO。
这些可以是三个独立的类,可以彼此独立使用,也可以使单元测试更容易
编辑2:
啊,所以如果你想确保用户获得有关DTO的统计信息,那么你可以将其作为DTO创建过程的一部分返回。因此DomainToDTOConverter使用DTOStaisticsCalculator,并在调用后返回DTO和有关DTO的统计信息。这样,您就知道用户已收到它们。
当然,您无法确保以任何有意义的方式使用这些统计信息。
答案 1 :(得分:0)
解决这个问题的一种方法是利用战略模式。
创建一个通用界面:
public interface IMethod
{
int MethodSequence { get; }
void RunMethod();
}
然后你可以拥有自己的方法:
public class MethodA : IMethod
{
public int MethodSequence => 1;
public void RunMethod()
{
Console.WriteLine("Ran Method A");
}
}
public class MethodB : IMethod
{
public int MethodSequence => 2;
public void RunMethod()
{
Console.WriteLine("Ran Method B");
}
}
public class MethodC : IMethod
{
public int MethodSequence => 3;
public void RunMethod()
{
Console.WriteLine("Ran Method C");
}
}
现在创建上下文并按顺序运行方法:
public class RunMethods
{
public void Execute(IEnumerable<IMethod> methods)
{
methods.OrderBy(method => method.MethodSequence)
.ToList()
.ForEach(method => method.RunMethod());
}
}
您的调用代码将成为方法的任意组合:
var runMethods = new RunMethods();
runMethods.Execute(new List<IMethod>
{
new MethodA(),
new MethodB()
});