【问题标题】:If database triggers are evil, is it also evil to have side effects when setting a property in java or C#?如果数据库触发器是邪恶的,那么在 java 或 C# 中设置属性时产生副作用也是邪恶的吗?
【发布时间】:2010-12-01 14:43:23
【问题描述】:

假设[数据库触发器是邪恶的]。1

这是否意味着在 java 或 C# 对象上设置属性时的副作用也是邪恶的?

在我看来,所有相同的问题都存在。

【问题讨论】:

    标签: c# java getter-setter


    【解决方案1】:

    在这里不合时宜...

    属性不应触发副作用。这就是 Method 的用途。

    通过让属性导致副作用,您最终会陷入代码基本上被隐藏的情况。人们很少期望物业启动某些过程或导致其他事情发生翻转。如果这必须记录在案,那么它并不明显并且会被忽略。

    但是,我们确实希望在调用方法时会发生一些事情。

    以@astander 为例,他说更改“价格”的行为应该导致不同的属性“成本”发生变化。但是,如果我们稍后添加一个名为“折扣”的新属性会怎样? Price 和 Amount 属性的代码必须更改。这不是很容易发现。

    但是,如果 Cost 自己计算..那么一切都会变得更好。

    【讨论】:

      【解决方案2】:

      不一定,不。如果您有PriceAmount 属性,并且您更改了它,那么Cost 似乎应该相应更改?

      或者你对这篇文章有什么不同的想法?

      【讨论】:

      • @Michael Petrotta,谢谢,拼写不是我的强项 X-)
      • 呵呵,没问题。我对拼写有点眼光,还有强迫症。
      • 有一种思路说你应该在这种情况下使用方法,因为除了给定值的设置之外还有副作用。我不确定我是否同意这一点,但我确实理解它的意思。
      • 我认为这是一个不好的例子,因为我会在请求时计算成本,而不是在价格或金额属性更改时计算。
      【解决方案3】:

      没有。许多属性可以而且应该触发副作用。

      例如:想象两个视觉元素,其中一个子元素包含在一个父元素中。设置 parent.Visible = false 也应该设置 child.Visible = false。

      这些副作用通常通过事件(System.Windows.Forms 充满了 PropertyChanged 事件)或接口(例如 INotifyPropertyChanged)显式显示。

      【讨论】:

      • 设置 Control.Visible 实际上并不执行代码来显示或隐藏容器或子项。它只是一个标志,告诉 Draw 方法要做什么。
      【解决方案4】:

      虽然属性有时很有用,但它们确实会在团队环境中的日常编码中引入一些不确定性,在这种环境中,并非每个人都必须以相同的方式解释属性的用途和适当使用。

      这是出现的许多问题之一:

      • 属性设置器是否应该有不明显的副作用。
      • 他们是否应该进行潜在的密集处理?
      • 公共字段是否仍有位置,或者所有字段都应该是私有的/受保护的并通过属性访问?这在使用反射时会产生影响:知道您永远不必搜索类型的 Fields 集合会很方便。

      最后,我认为以上两点并不重要,只要记录了任何副作用或可能代价高昂的操作,因为同样的方法也应该适用于方法。

      您可以安全地做出更多假设来降低代码复杂性,但这种收益在某种程度上被额外的通信开销所抵消。仅当团队中的每个人都在同一页面上并且保持在同一页面上时,它才有效。

      有时我认为属性导致的问题多于它们解决的问题。

      【讨论】:

        【解决方案5】:

        这取决于。当然会有副作用,这会让用户大吃一惊,最好避免那些 IMO。

        我更喜欢属性的行为与字段非常相似,因为从读者的角度来看它们看起来是一样的(无论如何在 C# 中)。如果一个属性有任何不明显的副作用,我更喜欢方法而不是属性。

        【讨论】:

        • 正如我在其他地方所建议的那样,这里的方法和属性不是处于相同的情况吗?如果在任何一种情况下都有一些不明显的影响,这不应该反映在方法/属性名称中或以某种方式记录吗?我只是不明白在方法后面隐藏意外结果如何让事情变得更好。
        • @Quick Joe Smith:这是一个公平的观点,但是从 C# 调用者的角度来看,字段和属性看起来完全相同,调用者无法轻易发现副作用的风险。
        【解决方案6】:

        除了上面 Chris 的 cmets 之外,我确实同意这一点,还有另一个方面导致触发器被认为有点曲折,那就是它们不明显的事实。

        这使得它们很容易被遗忘,这反过来又使它们很难调试。

        人们(我肯定是其中之一,而不是唯一一个)已经花费了数小时尝试调试问题并从头到尾遍历流程(明显结束,即数据库过程/DML 查询)以了解导致问题的原因问题一直是触发器 - 因为它们本质上是后台操作。

        您也可以争辩说,正确记录触发器应该可以轻松避免此类问题,但通常日志记录永远不会在数据库层本身中完成,因此这方面的故障排除更加复杂。

        【讨论】:

          猜你喜欢
          • 2010-10-02
          • 2011-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-07
          相关资源
          最近更新 更多