“Закрытия являются объектами бедного человека и наоборот” - Что это означает?

Закрытия являются объектами бедного человека и наоборот.

Я видел этот вмногиеоператор места в сети (включая ТАК), но я не вполне понимаю то, что это означает. Кто-то мог объяснить, что это точно означает?

Если возможно, включайте примеры в свой ответ.

57
задан Community 23 May 2017 в 12:10
поделиться

4 ответа

«Объекты - это закрытие для бедняков» - это не просто утверждение некоторой теоретической эквивалентности - это обычная идиома Java. Анонимные классы очень часто используются для завершения функции, фиксирующей текущее состояние. Вот как это используется:

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

Это даже очень похоже на эквивалентный код, использующий замыкание на другом языке. Например, с использованием блоков Objective-C (поскольку Objective-C достаточно похож на Java):

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

Единственное реальное отличие состоит в том, что функциональность обернута в экземпляр анонимного класса new Runnable () в Версия Java.

5
ответ дан 24 November 2019 в 19:23
поделиться

Дело в том, что закрытия и объекты достигают одной и той же цели: инкапсуляция данных и/или функциональности в единую логическую единицу.

Например, вы можете создать класс 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, состоящий из некоторых функций. Поскольку эти функции обращаются к данным, которые были выделены в локальной области видимости, память не восстанавливается, что позволяет продолжать использовать их через интерфейс, предоставляемый закрытием.

57
ответ дан 24 November 2019 в 19:23
поделиться

ОТРЕДАКТИРОВАНО: В названии вопроса нет слова "наоборот", поэтому я постараюсь не предполагать намерений спрашивающего.

Два общих лагеря - это функциональные и императивные языки. Оба они являются инструментами, которые могут решать схожие задачи разными способами с разными наборами проблем.

Замыкания - это объекты бедного человека.

Объекты - это бедные мужские закрытия.

Каждое утверждение по отдельности обычно означает, что автор имеет некоторую предвзятость, так или иначе, обычно коренящуюся в его комфорте с одним языком или классом языков против дискомфорта с другим. Если это не предвзятость, то они могут быть ограничены той или иной средой. Авторы, которых я читаю и которые говорят подобные вещи, обычно являются фанатиками, пуристами или языковыми религиозными типами. Я по возможности избегаю религиозных языковых типов.

Замыкания - это бедные мужские объекты. Объекты - это бедные мужские закрытия.

Автор этого - "прагматик" и к тому же довольно умен. Это означает, что автор ценит обе точки зрения и считает, что они концептуально одно и то же. Это мой соратник.

7
ответ дан 24 November 2019 в 19:23
поделиться

В простейшем случае объект - это просто набор состояний и функций, которые работают с этим состоянием. Замыкание - это также набор состояний и функция, которая работает с этим состоянием.

Допустим, я вызываю функцию, которая принимает обратный вызов. В этом обратном вызове мне нужно работать с некоторым состоянием, известным до вызова функции. Я могу создать объект, который воплощает это состояние («поля») и содержит функцию-член («метод»), которая выполняет функцию обратного вызова. Или я мог бы пойти быстрым и легким («бедняжским») путем и создать закрытие.

Как объект:

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);
}

Это псевдо-C #, но он похож по концепции на другие объектно-ориентированные языки. Как видите, в классе обратного вызова задействовано довольно много шаблонов для управления состоянием. Было бы намного проще использовать замыкание:

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

Это лямбда (опять же, в синтаксисе C #, но концепция аналогична в других языках, поддерживающих замыкания), которая дает нам все возможности класса без необходимости писать, использовать и поддерживать отдельный класс.

Вы также услышите следствие: «объекты - это закрытие для бедняков». Если я не могу или не хочу воспользоваться закрытием, то я вынужден выполнять свою работу, используя объекты, как в моем первом примере. Хотя объекты обеспечивают большую функциональность, закрытие часто является лучшим выбором там, где закрытие будет работать, по уже указанным причинам.

Следовательно, бедняк без объектов часто может выполнять свою работу с помощью замыканий, а бедняк без замыканий может выполнять свою работу с помощью объектов. У богатого человека есть и то, и другое, и он использует подходящую для каждой работы.

14
ответ дан 24 November 2019 в 19:23
поделиться