我们正在设计一个仅供内部使用的库,它将作为几个即将推出的应用程序的核心业务对象模型。它主要涵盖各种类型的客户和各种类型的文件。
显然,我们希望确保如果您要使用这些对象,特别是如果您要对它们进行序列化,那么它们就具有有效,合理的值。
例如,客户有联系信息,其中包括电话号码。所以这里有ITelephoneNumber
接口,基类,美国实现。该库使用这些类来验证其数据。
但实际上,对我们来说,客户更像是一个“核心”业务对象,而对于我们来说,电话号码则更少;为电话号码编写一堆结构感觉有点奇怪,并将其暴露为Our-Library-Goodness。它们似乎“超出了范围”。
电话号码就是一个例子;还有其他的事情。我们可以将这些类结构重构为静态方法,但是我们有冗长的构造函数,他们必须“只知道”才能使用这些方法等。我们决定使用类来实现这一点。
库使用者是否必须使用这些对定义核心对象不必要的辅助类?如:
MyCustomer.SetTelephoneNumber(new USTelephoneNumber("555", "555", "5555%$&"));
为您提供编译时反馈,自己的成员(AreaCode,Exchange ...)等等。
或者我们应该只是将有效的电话号码留给实施方式,并且更加“黑匣子”呢?如:
MyCustomer.SetTelephoneNumber("555-555-5555%$&");
只会抛出错误或无声地失败/成功或返回string.Empty或其他。
我不知道这个问题是否可以“回答”,我不想开始任何神圣的战争。无论哪种方式,我都在寻找一些推理。我们只是一个2人团队,试图在一个不关心代码质量或可维护性的机构中做正确的事情。
答案 0 :(得分:1)
正如您所说,这个问题可能无法回答。所以这不是答案,但是(因为评论太长了)我会在这里写下来:
我会选择两个选项,为SetTelephoneNumber
您的客户课程如何知道如何将电话号码验证为美国号码?如果您假设美国客户将拥有美国电话号码,则在某些情况下该假设可能是错误的。因此,有一个“简单”覆盖来处理最可能的情况,并且覆盖允许您指定不常见的情况,这是公平的。
如果您可以为电话号码注入不同类型的验证逻辑,而不是让它们在课堂上“隐藏”,那么您的系统也将变得更容易测试。
那就是说,我不会过分夸大这一点。 “尝试做正确的事”很好,但也容易陷入FizzBuzz Enterprise Edition综合症。
答案 1 :(得分:1)
电话号码似乎是您网域的一部分,因此请将其曝光。理想情况下,整个应用程序中的所有代码都将共享此电话号码对象并对其进行标准化。也许它甚至应该存在于较低层(数据格式库左右,与客户等高级对象无关)。
答案 2 :(得分:1)
这个问题的关键在于你说它是一个“内部唯一的库”。这意味着完全由内部开发团队来确定库的实现方式。为了做出这些决定,我会看看两种实现可能性的价值。
更复杂的实现是否可以节省您以后开发的时间和精力?
当您使用库时,更复杂的实现是否会阻止您反复编写验证代码?
这些问题可以帮助您确定复杂的实施是否有价值。如果预先编码可以节省您的长期时间,那么它是值得的。如果预先编码在可预见的将来不会节省时间和精力,那么这是不值得的。