C#/面向对象的设计 - 维护有效的对象状态(C# / Object oriented design

2019-09-18 15:10发布

当设计一个类时,应逻辑以保持有效状态中的类被掺入或在它之外? 也就是说,应该性质扔在无效状态的异常(即,值超出范围,等等),或者被构建的类的实例时的/修改应此验证被执行?

Answer 1:

它所属的类。 无非类本身(及任何助手它代表们)应该知道,或者,决定有效或无效状态的规则有关。



Answer 2:

是的,性能应检查的有效/无效值被设置时。 这就是它是。



Answer 3:

这应该是不可能把一个类为无效状态,无论代码的外面。 这应该说清楚。

在另一方面,外面的代码仍然是负责正确使用类,所以经常会是有意义的检查两次。 类的方法可能会抛出ArgumentException ,如果通过一些他们不喜欢的,调用代码应该确保通过在地方正确的逻辑来验证输入等,这不会发生

也有更复杂的情况下,也有参与系统客户端的不同“级别”。 一个例子是OS - 应用程序在“用户模式”运行,并且应该是不能把OS为无效状态的。 但司机“内核模式”运行,完全能够破坏操作系统状态的,因为这是一个团队,是负责执行的应用程序使用的服务的一部分。

这种双电平结构的可发生在对象模型; 有可能是模型,只看到有效状态的“外部”的客户,和“内部”客户端(插件,扩展,插件),它必须能够看到什么,否则将视为“无效”状态,因为他们有一个角色在执行状态转换播放。 无效/有效的定义取决于角色由客户正在播放的不同。



Answer 4:

一般来说,这属于在类本身,而是在一定程度上它也取决于你的“有效”的定义。 例如,考虑System.IO.FileInfo类。 它是有效的,如果它是指文件不再存在? 它怎么会知道?



Answer 5:

我会@Joel同意。 Typcially这将在类中找到。 不过,我不会有属性访问器实现验证逻辑。 相反,我建议一个验证方法为持久层的对象被持续时调用。 这使您可以本地化验证逻辑在一个地方,并作出不同的选择为有效/无效的基础上正在执行的持久性操作。 如果,例如,您计划从数据库中删除一个对象,你关心它的一些属性是无效的? 大概不会 - 只要ID和行版本是相同的数据库,你先走一步,将其删除。 同样的,你可能有插入和更新,如不同的规则,一些领域可能会在插入空,但更新所需。



Answer 6:

这取决于。

如果验证是简单的,并且可以使用只包含在类信息进行检查,然后大部分的时间是值得的状态检查添加到类。

有时有,但是,它不是真正的或不宜这样做。

一个很好的例子是一个编译器。 检查抽象语法树(AST的)的状态,以确保程序是有效的通常不是由任一属性setter方法或构造函数来完成。 相反,验证通常是由树访问者,或一系列的某种“语义分析类”的相互递归的方法来完成。 在这两种情况下,但是,性能进行验证后不久它们的值设置。

此外,与使用旧UI状态通常是一个坏主意(从可用性的角度来看)时,无效的值设置为抛出异常对象。 这是使用WPF数据绑定应用程序尤其如此。 在这种情况下,你想显示某种模态的反馈给客户,而不是抛出异常。



Answer 7:

该类真的应该保持有效的值。 如果这些是通过构造函数或通过属性中输入它不应该的问题。 双方应该拒绝无效值。 如果这两个构造函数的参数和性能要求相同的验证,您可以使用一个共同的私有方法来验证值的属性和构造都或者你可以在属性做验证和使用您的构造函数中的属性设置时局部变量。 我会建议使用一个共同的验证方法,个人。

如果它收到无效值类应抛出异常。 总而言之,好的设计可以帮助减少这种情况发生的几率。



Answer 8:

一个类中的有效状态与类的不变理念最好的表达。 这是一个布尔表达式该类的对象是有效的,必须成立。

契约式设计的方式暗示你,为C类的开发者,应该保证类不变成立:

  • 施工完毕后
  • 到公共方法的调用后

这将意味着,由于对象封装 (没有人可以改变它,除非通过调用公共方法),不变也将在进入任何公开的方法来满足,或者在进入析构函数(与析构函数语言),如果有的话。

每个公共法规定,将由类在每一个公共方法结束满足的先决条件 ,调用者必须满足,和后置条件 。 违反的前提条件有效违反类的合同,所以它仍然可以是正确的,但它并没有任何特定的行为方式,也保持不变,如果它被称为一个前提冲突。 是履行其在没有来电者违反合同的类可以说是正确的

从正确的不同,但它补充(当然属于软件质量的多重因素)的一个概念是稳健的 。 于我们而言,一个强大的类将检测时,它的一个方法被称为不履行方法的前提条件。 在这种情况下,断言冲突异常通常会被抛出,从而使来电者知道,他搞砸了。

所以,回答你的问题,无论是类和它的调用者有责任为类合同的一部分。 一个强大的类将检测违反合同和口水。 正确的来电者将不会违反合同。

属于一个代码库的公共接口的类被编译为强劲,而内部类可以作为强大的测试,但在随后发布的产品刚刚正确运行,而不为前提检查。 这取决于很多事情,并在其他地方讨论 。



文章来源: C# / Object oriented design - maintaining valid object state
标签: c# oop state