简体   繁体   English

为什么在类属性中没有复杂的逻辑被认为是最佳实践?

[英]Why is considered best practice to have no complex logic in class properties?

What are the cons of some code like this: 这样的代码有什么缺点:

public class Class1
{
   public object Property1
   {

        set 
        {
             // Check some invariant , and null

             // throw exceptions if not satisfied

             // do some more complex logic

             //return value 
        }

   }
}

The con would be that if you are doing excessive logic that takes a great period of time, and/or has side effects which don't logically flow from the setting of the property, you are going to have a pretty convoluted class design. 如果你做了过多的逻辑需要花费很长一段时间,和/或副作用不能从属性的设置中逻辑流动,那么你将会有一个非常复杂的类设计。

Methods are traditionally used to indicate that an action with consequence is being performed, not properties. 传统上,方法用于表示正在执行具有后果的动作,而不是属性。 While you definitely can have logic in them, having too much might give the wrong impression of what you are trying to do, which is assign a value, as opposed to perform an operation. 虽然你肯定可以在其中使用逻辑,但是过多可能会给你错误的印象,即你要做什么,分配一个值,而不是执行一个操作。

In the end, it all depends on what "do some more complex logic" means. 最后,这一切都取决于“做一些更复杂的逻辑”的含义。

It's hard to answer the question since "complex logic" is very vague. 由于“复杂逻辑”非常模糊,因此很难回答这个问题。

I see no issues with basic sanity checking on setting of a property and it's very common to need to do some sort of processing on an object when one of its properties changes. 我发现在设置属性时基本的健全性检查没有问题,当一个属性发生变化时,需要对对象进行某种处理是很常见的。

Now, if by "complex logic" you mean do things like some crazy database access or creating a network connection to go do something then yes, that would be bad. 现在,如果用“复杂的逻辑”你的意思是做一些像疯狂的数据库访问或创建网络连接去做某事然后是的,这将是坏事。

If you see a property, you assume that it behaves just like a field, ie, that you can retrieve its value over and over again: 如果你看到一个属性,你会认为它的行为就像一个字段,即你可以一遍又一遍地检索它的值:

if(obj.Prop.Equals(otherObj.Prop))
{
    Console.WriteLine(obj.Prop);
    Log.CreateEntry(obj.Prop);
}

Were Prop implemented as a method. Prop是作为一种方法实现的。 The users suspects expensive computation and will probably copy the result into a local variable and work on it instead. 用户怀疑昂贵的计算,并且可能会将结果复制到局部变量中并对其进行处理。

A property must never change the object. 属性绝不能更改对象。 A property should always return the same object if it's value hasn't changed. 如果属性值未更改,则属性应始终返回相同的对象。 Especially if the creation of the object is expensive (like returning a new StreamReader on every call) 特别是如果对象的创建很昂贵(比如在每次调用时返回一个新的StreamReader)

Properties should strive to be side effect free. 属性应力求无副作用。 IF the side effect is invisible to consumers of the class (a lazy creation of a string which then doesn't change) then this is much less of an issue. 如果副作用对于类的消费者是不可见的(一个字符串的懒惰创建然后不会改变)那么这不是一个问题。 By default debuggers tend to display (thus evaluate) properties. 默认情况下,调试器倾向于显示(从而评估)属性。 If they have side effects this can cause considerable grief. 如果它们有副作用,这可能会导致相当大的悲伤。

Throwing from a setter if the supplied value is illegal is generally okay. 如果提供的值是非法的,则从设置者投掷通常是可以的。 Throwing from a getter is generally considered poor. 从吸气剂投掷通常被认为是差的。

These are, as ever, rules of thumb and circumstances can dictate that they are not followed. 这些都是,一如既往,经验法则和环境可以规定它们不会被遵循。 A good example is the properties on the types generated via Linq to SQL. 一个很好的例子是通过Linq to SQL生成的类型的属性。 If you have lazy lookup of child properties then evaluating it does indeed trigger a database read. 如果您对子属性进行了延迟查找,那么对它进行评估确实会触发数据库读取。 This is offset but the ease of use, readability and consistency of the resulting objects - it's one of those balancing competing rules things. 这是偏移但是易于使用,可读性和结果对象的一致性 - 它是平衡竞争规则的东西之一。

Be wary of rules that say MUST or NEVER. 警惕那些必须或永远不会说的规则。 Sometimes rules of this nature exist, and are reasonable, but they are actually uncommon. 有时这种性质的规则存在,并且是合理的,但它们实际上并不常见。

Properties are expected be cheap to execute. 预计属性执行起来很便宜。 Code looks tidier if the value of the property doesn't need to be held in a variable to avoid expensive property code execution. 如果属性的值不需要保存在变量中以避免昂贵的属性代码执行,则代码看起来更整洁。

The same goes for setting them, its not expected that assigning a value will invoke some expensive operation. 设置它们也是如此,不期望分配值会调用一些昂贵的操作。

For clarity of code business logic should be separate from the property setters. 为了清晰起见,业务逻辑应该与属性设置者分开。 Uncomplicated sanity checks can and should often take place in the property. 简单的健全检查可以而且应该经常在酒店内进行。 But anything that is application specific, or not immediately implicit in the type should be abstracted away. 但是任何特定于应用程序的东西,或者不是立即隐含在类型中的东西都应该被抽象掉。 For best OO practices You would want any logic that applies only to that object to be part of that object, and any complicated logic that relates to how you DEAL with that object should be in the part of the code that deals with handling the object. 对于最佳OO实践您可能希望任何仅适用于该对象的逻辑成为该对象的一部分,并且任何与您对该对象进行交易相关的复杂逻辑应该位于处理该对象的代码部分。

For a code to be understandable, it's better if you can get exactly what you have just set . 为了使代码易于理解,最好能够get刚刚set

Except for "some complex logic", which we cannot see for now, this code doesn't look like a big mess. 除了一些我们现在看不到的“复杂逻辑”之外,这段代码看起来并不是一团糟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM