代码之家  ›  专栏  ›  技术社区  ›  missingfaktor Kevin Wright

“封闭是穷人的目标,反之亦然”——这是什么意思?

  •  53
  • missingfaktor Kevin Wright  · 技术社区  · 15 年前

    封闭是穷人的目标,反之亦然。

    我看过这个声明 at many places 在网络上 including SO )但我不太明白这是什么意思。有人能解释一下这到底是什么意思吗?

    如果可能的话,请在你的回答中包括一些例子。

    6 回复  |  直到 9 年前
        1
  •  55
  •   miikkas    11 年前

    关键是闭包和对象实现了相同的目标:将数据和/或功能封装在单个逻辑单元中。

    例如,您可以创建一个python类来表示这样的狗:

    class Dog(object):
        def __init__(self):
            self.breed = "Beagle"
            self.height = 12
            self.weight = 15
            self.age = 1
        def feed(self, amount):
            self.weight += amount / 5.0
        def grow(self):
            self.weight += 2
            self.height += .25
        def bark(self):
            print "Bark!"
    

    然后我将类实例化为一个对象

    >>> Shaggy = Dog()
    

    shaggy对象内置了数据和功能。当我呼唤 Shaggy.feed(5) ,他赚了一英镑。磅存储在变量中,变量作为对象的属性存储,这或多或少意味着它在对象的内部作用域中。

    如果我在编写一些javascript代码,我会做类似的事情:

    var Shaggy = function() {
        var breed = "Beagle";
        var height = 12;
        var weight = 15;
        var age = 1;
        return {
            feed : function(){
                weight += amount / 5.0;
            },
            grow : function(){
                weight += 2;
                height += .25;
            },
            bark : function(){
                window.alert("Bark!");
            },
            stats : function(){
                window.alert(breed "," height "," weight "," age);
            }
        }
    }();
    

    在这里,我不是在对象中创建作用域,而是在函数中创建作用域,然后调用该函数。函数返回由一些函数组成的javascript对象。因为这些函数访问在本地作用域中分配的数据,所以不会回收内存,从而允许您通过闭包提供的接口继续使用它们。

        2
  •  55
  •   Miikka    11 年前

    物体是穷人的封闭物。

    考虑Java。Java是一种面向对象的编程语言,对实际的词汇闭包没有语言级支持。作为Java程序员的一项工作,使用匿名内部类可以关闭在词法范围中可用的变量(前提是它们是 final )。从这个意义上说,物体是穷人的封闭物。

    闭包是穷人的东西。

    想想哈斯克尔。haskell是一种函数式语言,不支持真正的对象。但是,可以使用闭包对它们进行建模,如 this 奥列格·基瑟里夫和拉尔夫·拉梅尔的优秀论文。从这个意义上说,闭包是穷人的目标。


    如果您来自一个oo背景,您可能会发现用对象来思考会更自然,因此可能会认为它们是比闭包更基本的概念。如果您来自一个fp背景,您可能会发现用闭包来思考更自然,因此可能会认为闭包是一个比对象更基本的概念。

    这个故事的寓意是 闭包和对象是可以相互表达的概念,没有一个比另一个更基本 . 这就是正在考虑的声明的全部内容。

    在哲学上,这被称为 model dependent realism .

        3
  •  14
  •   P Daddy    14 年前

    一个对象,最简单的说,就是一个状态和操作该状态的函数的集合。闭包也是一个状态集合和一个对该状态进行操作的函数。

    假设我调用一个接受回调的函数。在这个回调函数中,我需要对函数调用之前已知的一些状态进行操作。我可以创建一个包含此状态(“fields”)的对象,该对象包含一个执行回调的成员函数(“method”)。或者,我可以采取快速和简单的路线(“穷人的”)并创造一个关闭。

    作为一个对象:

    class CallbackState{
        object state;
    
        public CallbackState(object state){this.state = state;}
    
        public void Callback(){
            // do something with state
        }
    }
    
    void Foo(){
        object state = GenerateState();
        CallbackState callback = new CallbackState(state);
        PerformOperation(callback.Callback);
    }
    

    这是pseudo-c,但在概念上与其他oo语言相似。如您所见,有相当数量的样板文件涉及到回调类来管理状态。使用闭包会简单得多:

    void Foo(){
        object state = GenerateState();
        PerformOperation(()=>{/*do something with state*/});
    }
    

    这是一个lambda(同样,在c语法中,但是这个概念在其他支持闭包的语言中是相似的),它为我们提供了类的所有功能,而不必编写、使用和维护单独的类。

    你也会听到推论:“物体是穷人的终结”。如果我不能或者不会利用闭包,那么我就不得不使用对象来完成他们的工作,如我的第一个例子所示。尽管对象提供了更多的功能,但是闭包通常是闭包工作的更好选择,原因已经说明。

    因此,没有对象的穷人通常可以使用闭包完成工作,而没有闭包的穷人可以使用对象完成工作。有钱人有两样东西,每一份工作都用对。

        4
  •  6
  •   mrjoltcola    15 年前

    编辑:题目不包括“反之亦然”,所以我尽量不假设提问者的意图。

    两种常见的阵营是函数式语言和命令式语言。两者都是可以用不同的关注点以不同的方式完成类似任务的工具。

    闭包是穷人的东西。

    物体是穷人的封闭物。

    就个人而言,每一句话通常意味着作者有某种偏见,不管是以何种方式,通常根源于他们对一种语言或一类语言的舒适感还是对另一种语言的不舒适感。如果没有偏差,它们可能会受到一个或另一个环境的约束。我读过的作者说,这类事情通常是狂热者、纯粹主义者或语言宗教类型。我尽量避免使用宗教语言。

    闭包是穷人的东西。物体是穷人的封闭物。

    这本书的作者是一位“实用主义者”,而且相当聪明。这意味着作者欣赏这两种观点,并欣赏它们在概念上是一致的。这是我那种人。

        5
  •  5
  •   Chuck    15 年前

    “对象是穷人的封闭”不只是一个理论等价的陈述,它是一个普通的Java习语。使用匿名类包装捕获当前状态的函数是非常常见的。使用方法如下:

    public void foo() {
        final String message = "Hey ma, I'm closed over!";
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                System.out.println(message);
            }
        });
    }
    

    这甚至看起来很像在另一种语言中使用闭包的等效代码。例如,使用C语言块(因为C语言与Java相当相似):

    void foo() {
        NSString *message = @"Hey ma, I'm closed over!";
        [[NSOperationQueue currentQueue] addOperationWithBlock:^{
            printf("%s\n", [message UTF8String]);
        }];
    }
    

    唯一真正的区别是,功能包装在 new Runnable() Java版本中的匿名类实例。

        6
  •  5
  •   DaGreek    14 年前

    就像闭包将匿名对象隐藏在裙子下面一样,这真是太好了。