长参数列表与长状态变量列表


10

在C ++书中,作者说我们不再需要带有长参数列表的函数,因为大多数参数都可以重构为类中的状态变量。另一方面,一本功能性的编程书说状态变量是有害的,因为它会引起副作用,导致副作用,导致易错和难以并行化代码。我很困惑。代码是否应该通过将其状态变量移到函数参数列表中来避免尽可能多地依赖状态变量?


原始书是否在评论C ++是一种功能语言?
马丁·约克

Answers:


7

取决于您是在procedural还是functional范式中编程。前者需要可变状态,而后者则需要削弱。这是苹果和橘子。他们在bailiwicks上都是正确的!

您可以将单一分配和其他功能技术应用于命令式过程语言,不可变状态使并发编程更具确定性,但是几乎不可能使每个对象都像Java或C ++这样不可变,因为它们的内存模型不容易支持这种范例。


:谢谢!这本书《每个程序员都应该知道的97件事》说,我们应该应用函数式编程原理,例如避免副作用。我们不能在命令式代码上下文中应用函数式编程原理吗?
TomCaps 2011年

是国家没有 所需的过程编程。这很常见,但不是必需的。普遍是更多的原因是习惯。尽管我承认,在某些情况下,保持(状态)变量比其他方法(例如异步处理)容易得多。
Marjan Venema

@Marjan任何具有不变变量的东西都是状态

@Jarrod:现在你让我感到困惑。再次阅读您的答案,我发现我错过了“必须处于可变状态”中的“可变”。但是您的评论似乎说,拥有不可变的变量是状态。不明白 可能是因为我不习惯在这些术语上乱扔而思考可变的和不变的。有什么参考资料可供我阅读吗?
Marjan Venema

@MarjanVenema:是的,拥有不可变的变量就是状态。程序和功能编程之间的处理状态差异不是proc.prog。具有状态,而功能没有-区别在于proc。编 状态具有可变状态,而状态在(纯)函数式编程中始终是不可变的。参见例如en.wikipedia.org/wiki/Purely_functional,它解释说纯功能语言避免更新。
sleske 2011年

1

如果我理解您的问题是对的,那么您正在质疑哪些条件可以使用参数或使用类变量/成员/字段/等?我假设您指的是方法,而不是函数。如果这是专门针对C ++的,我建议将您的问题移至堆栈溢出。

较长的参数列表可能表明您可能需要将您的方法重构为一组更精细的方法。通常,使用参数将使您的代码更松散地耦合。我不确定现在是否适用于大多数现代OO语言,但是对象创建会很昂贵,尤其是在涉及许多类变量的情况下;因此,如果您的类变量是对象并且在程序中经常被引用,则它们可能被证明是类变量。

也:

  • 其他方法可以利用类变量吗?如果是,则考虑使用类变量。
  • 您的方法公开吗?如果是公共的,请使用参数。
  • 您的参数列表可以适当地表示为哈希/映射/数组/集合/列表/等吗?如果是这样,请考虑使用它。
  • 您的方法是静态的吗?如果是,请使用参数。

0

不,状态变量本身不会引起副作用。

调用setter方法(在其他位置可见的数据结构上)一种副作用。

您可以使用数据结构来隐藏长参数列表和ansd,但如果相应地构造它们,则可以避免副作用。这是一个小示例(在Java中,未经测试):

class ManyParams {
    final String theName = null;
    final int    theAge = 0:
    ManyParams() {}
    ManyParams(String a, int b) { theName=a; theAge = b; }
    public withName(String n) {
        return new ManyParams(n, this.theAge);
    }
    public withAge(int i) {
         return new ManyParams(theName, i);
    }
}
/// to be used like this
foo(new ManyParams.withName("John").withAge(42));

当然,ManyParams的构造函数仍然会以这种方式包含较长的参数列表。但是它是隐藏的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.