3

对于公共界面,这将是一个更好的设计:

WriteValue(DeviceValueType.MachineName,"micks machine");

或者

WriteMachineName("Micks machine");

如果您使用类型 1,那么您只需要一个这样的通用接口,并且您可以通过将项目添加到枚举来写入任意数量的DeviceValueType 。

第二种类型更具体,因为它只会将值写入由其方法名称表示的特定类型。但是这些方法在类型安全方面有很大的优势。

例如:让我们考虑另一种类型

WriteValue(DeviceValueType.SleepDelay,"25");

WriteSleepDelay(25);

请注意,此处类型 2 具有优势,因为我可以指定预期的类型。如果我要使用类型 1,那么我必须将值转换为 int,然后如果值不在预期范围内,则抛出异常。如果我必须传递复杂类型,这将变得更加困难。

总而言之:

类型 1:通用。该接口只需要公开一种方法。参数没有类型安全。类型 2:特定的。该接口将需要与类型一样多的方法。键入安全。

解决此问题的一般建议方法是什么?

我正在使用 C#,但我相信这个问题与语言无关。

4

4 回答 4

1

您应该避免所谓的类型 1 接口。从经验来看,这类界面往往很快就会变得混乱。以睡眠延迟为例。您将如何键入检查该字符串是否为正整数?你最终会得到一个巨大的 switch 语句。所以至少封装它。

尽管您的类型 2 更好,但应注意它将写入操作与写入所需的数据紧密结合。我不知道您正在处理的要求(一次写入多次读取?),但是您的 DeviceValueType 枚举建议您可以简单地声明一个具有类似属性的 DeviceConfig 类,machine name并将sleep delay其传递给将执行实际工作的 Device 或 DeviceWriter 类. 但是,如果 machine name是配置,而sleep delay实际上是一种方法,您应该考虑将这两个问题也分开(即 Device.sleep() 和 Device.writeConfig(DeviceConfig))。

于 2013-05-07T07:30:09.580 回答
1

我来自 Python 背景,但实际上我会选择这两个选项。创建 WriteValue 函数,并让它完成所有繁重的工作。然后,将 WriteMachineName 和 WriteSleepDelay 函数编写为 WriteValue 的简单包装器。这样,您就可以对所有经常使用的函数使用简写函数,对不经常调用的所有函数使用长版本。

不过,您可能希望在文档中明确说明其工作方式,以便在您知道如何以及为什么这样做之后必须使用它的人。

另外:我不知道 C# 中的函数调用有多昂贵。如果它们非常昂贵(在 CPU 时间中),您可能希望始终使用类型 1。

于 2013-05-07T06:57:44.157 回答
0

首先:我不知道这种情况的一般规则或设计模式,因此我写了我会做的事情。

如果您不关心参数的类型,请执行以下操作WriteValue("micks machine");。但是不要做任何技巧,比如格式化整数与字符串等不同,只需简单地写下你得到的字符串,让调用者进行翻译。(类型 0)

我永远不会做像你的类型 1 的事情。为什么?您提到了一些原因(类型安全)。但也为了可读性:你最终会做 swtiches 或 if-then-elses。而且,如果您关心干净的代码,您最终也会编写带有类似签名的私有辅助方法WriteMachineName("Micks machine");(如类型 2)。

我更喜欢类型 2,可能与简单类型的类型 0 混合,例如WritePlain("Micks machine"); WriteNumber(3.4);

注意:在类型 1 和 2 中,您将一些业务代码移至这些方法。这既不好也不坏,但您必须选择它是否适用于您的案例(连贯性)。相比之下,类型 0 将转换逻辑从类型转换为该类中的字符串。

于 2013-05-07T10:04:56.243 回答
0

这取决于 :)

此外,第三种可能性是两者都做:使用正确的参数具有通用WriteValue() 特定的“WriteSleepDelay() which in turn callsWriteValue()”。如果这些方法的实现相当复杂,即如果您有很多冗余代码,除非您将其集中到泛型方法中,否则这是有道理的。

对于一个(大概)简单的事情WriteValue,为了简单起见,我会使用单独的方法。

更新:对于继承层次结构,在基接口中有泛型方法是有意义的。然后,派生类可以添加仅对它们WriteSleepDelay()有意义的其他类型安全方法(例如)。

或者,您可能希望在子类WriteValue(Object value)中使用适当的类型安全变体覆盖基类(例如WriteValue(Integer),在子类中SleepTimer)。这很可能在您的具体情况下没有意义,但对于其他情况,它可能是理想的。

于 2013-05-07T07:00:10.213 回答