你使用旗帜还是做两次操作?

时间:2009-07-17 12:05:34

标签: web-services coding-style

今天出现了一个有趣的讨论,围绕着一个带有标志的方法和两个方法对于每个标志状态的概念。哪个更有意义,为什么?

void Submit(object data, bool isDraft);

void Submit(object data);

void SubmitAsDraft(object data);

我倾向于后者,每个操作都明确指出交易的执行情况。

哪个更有意义,是否存在众所周知的规则或模式?

修改

假设通过SOAP服务将方法公开为操作,并且OO概念不一定适用。虽然OO是服务背后的实现。

11 个答案:

答案 0 :(得分:12)

如果您使用单一功能,请不要使用bool,请使用枚举:

enum DocType { Draft, Final };

void Submit(object data, DocType type );

这有两个主要优点 - 它是在呼叫站点自我记录:

Submit( mydata, Draft );

如果您发现自己有两种以上的文档类型(或状态),它会自然延伸。

答案 1 :(得分:12)

我会这样做:

void Submit(object data) { _Submit(data, false); }
void SubmitAsDraft(object data) { _Submit(data, true); }
(private) void _Submit(object data, bool isDraft);

但那只是我......

答案 2 :(得分:5)

哪一个更具可读性?

Submit(data, true); // true what?
// vs
SubmitDraft(data);

我认为这里的答案是使用显式单独操作,如果您的编程语言不支持关键字参数,例如

Submit(data, isDraft: true);

答案 3 :(得分:4)

我个人去干;不要重复自己。如果两者之间有很多公共代码,请使用带有flag的方法。否则,有两种方法。

答案 4 :(得分:3)

另一种选择:使用枚举{DRAFT,FINAL_VERSION}而不是布尔值作为参数。

答案 5 :(得分:3)

使用对象概念,例如polymorphism; - )

data.submit()

dataDraftFinal。两个类都使用submit()方法实现相同的接口。

这样你就可以摆脱布尔糟糕的结构数据

答案 6 :(得分:2)

我会让IsDraft成为你传入的对象的属性,因为它似乎与对象有关。

答案 7 :(得分:1)

几乎所有给出的答案都是正确的,但似乎没有一个覆盖整个范围,所以 -

  1. 用于明显的语义,两个公共方法:

    SubmitFinal(数据)
    SubmitDraft(数据)

  2. 对于最小化实现,这两个公共方法调用一个内部方法:

    submitData(data,isDraft)

  3. 以便将来扩展,使用枚举而不是布尔值:

    submitData(data,DocType.Draft)

  4. 如果此选项可用,则将枚举附加到数据对象会更好,例如

    data.DocType = DocType.Draft;
    data.Submit();
    

答案 8 :(得分:0)

这里没有硬性规定。有时候,如果你按照“有不同的方法”规则过多,你的api会变得过于臃肿,你会对实际工作的实际方法感到困惑。但是,如果您按照“使用参数执行所有操作”的方法,最终只能使用一种方法将所有内容都指定为参数。

但是为了解决这个特定的例子,读取方法名称比读取参数更容易。在这种情况下,使用两种方法,您可以通过阅读可以提交草稿的方法名称来快速确定。虽然您应该将submit方法的名称更改为“submitAsFinal”

虽然我建议使用两个方法,一个名称为submitAsFinal而另一个名为submitAsDraft,但它们仍应推迟到另一个私有方法,该方法接受draft boolean参数,以便您没有重复的代码。

答案 9 :(得分:0)

我对这个问题感到非常伤心。我认为使用第二种方法更可靠,更容易调试。每个功能都变成一个非常清晰的黑盒子。错误更容易捕获,因为您可以在函数中捕获输入错误。将标志置于函数范围之外似乎会在代码中引入额外的歧义。在什么条件下我的功能被称为?我的旗帜在哪里以及为何?是否发生了一些逻辑错误导致标志设置不正确?它还使您必须在调用可能很复杂的函数之前测试标志的有效性。我认为删除标志可以在函数内部进行更好的封装,并且可以在函数内部一致地处理状态的错误处理。

但就像我说我被撕裂第一种方法可能非常方便,如果你在一个函数中有非常复杂的逻辑,它可以确保因为DRY的一致性。不需要重复真正脆弱和复杂的功能。

在我看来,我认为这取决于你最终想要验证输入参数的位置。我认为避免标志可以提供一个非常清晰的位置来追踪问题。在黑匣子里面。

此外,除了旗帜,有时我想知道谁和什么叫我的功能。所以有时候我会添加一个引用id作为附加参数。

void Submit(object data, bool isDraft, string referenceId);

然后我可以更多地了解谁正在调用提交,并且如果想要强制规定谁应该调用你的函数并理解它在逻辑流程中被调用的时间,那么可以更容易地追踪错误。

答案 10 :(得分:0)

我会创建两个单独的方法:

void Submit(object data);
void SubmitAsDraft(object data);

布尔参数习惯需要重构为枚举,如果不查找格式参数名称,则难以阅读。

然后,假设这些方法中存在一些共性,将公共部分考虑为通过上述两种方法的实现调用它们自己的方法。除非功能的唯一区别是在数据库中保存一个布尔字段,否则你不可能调用一些底层方法并传递一个布尔值。