Объект, в самом простом случае, это просто набор состояний и функций, которые работают с этим состоянием. Закрытие - это также набор состояний и функция, которая работает с этим состоянием.
Допустим, я вызываю функцию, которая принимает обратный вызов. В этом обратном вызове мне нужно оперировать некоторым состоянием, известным до вызова функции. Я могу создать объект, который воплощает это состояние («поля») и содержит функцию-член («метод»), которая выполняет функцию обратного вызова. Или я мог бы пойти быстрым и легким ("бедным человеком") маршрутом и создать замыкание.
Как объект:
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 #, но концепция аналогична в других языках, которые поддерживают замыкания), которая дает нам все возможности класса без необходимости писать, использовать и поддерживать отдельный класс.
Вы также услышите следствие: «объекты - это закрытие бедного человека». Если я не могу или не буду использовать преимущества замыканий, то я вынужден выполнять их работу, используя объекты, как в моем первом примере. Хотя объекты предоставляют больше функциональных возможностей, закрытие часто является лучшим выбором, когда закрытие будет работать по причинам, уже указанным.
Следовательно, бедняк без предметов может часто выполнять работу с замыканиями, а бедняк без замыканий может выполнять работу с использованием объектов. У богатого человека есть и то, и другое, и для каждой работы он подходит.