【发布时间】:2018-11-11 23:11:05
【问题描述】:
我是根据我在 cmets 中对这个问题的答案的一个小讨论来创建这个问题的:design a method returning a value or changing some data but not both
@Kata 指出 OP 感兴趣的模式称为 命令-查询分离,并认为这是构建代码的好模型。
来自wikipedia:
命令-查询分离 (CQS) 是命令式计算机编程的原则。它是由 Bertrand Meyer 设计的,是他在 Eiffel 编程语言方面的开创性工作的一部分。
它指出每个方法都应该是执行操作的命令,或者是向调用者返回数据的查询,但不能同时是两者。换句话说,问一个问题不应该改变答案。1 更正式地说,方法只有在引用透明并且没有副作用时才应该返回一个值。
我质疑这种设计原则的合理性,因为通常它会使您的代码显得更加乏味。例如:您不能执行像 next = Queue.Dequeue(); 这样的简单语句,您需要两条指令:一条用于修改数据结构,一条用于读取结果。
@Kata 发现了另一种 Stack 实现,乍一看似乎满足了两全其美的要求:从函数式编程中获取一页,我们将 Stack 定义为不可变的数据结构。每当我们 push(x) 时,我们都会创建一个新的 Stack 节点,它保存值 x 并维护一个指向旧的头 Stack 实例的指针。每当我们 pop() 时,我们只是返回指向下一个 Stack 实例的指针。因此我们可以坚持命令-查询分离原则。
示例堆栈实现:https://fsharpforfunandprofit.com/posts/stack-based-calculator/
但是,在这种情况下,不清楚的一件事是如何在保持命令-查询分离原则的同时保持对堆栈的多个引用同步?我没有看到明显的解决方案。因此,出于好奇,我向社区提出这个问题,看看我们是否找不到令人满意的解决方案:)
编辑:这是问题的一个例子:
s = new Stack();
s2 = s
...
s = s.push(x);
assert(s == s2); // this will fail
【问题讨论】:
标签: design-patterns functional-programming