Является ли функция примером инкапсуляции? - PullRequest
6 голосов
/ 10 февраля 2009

Включая функциональность в функцию, она сама по себе является примером инкапсуляции или вам нужно использовать объекты для инкапсуляции?

Я пытаюсь понять концепцию инкапсуляции. Я подумал, что если я уйду от чего-то вроде этого:

n = n + 1

, который выполняется в дикой природе как часть большого тела кода, а затем я беру это и помещаю в такую ​​функцию, как эта, затем я инкапсулировал эту логику добавления в методе:

addOne(n)
    n = n + 1
    return n

Или, скорее, это инкапсуляция, только если я скрываю детали addOne от внешнего мира - например, если это объектный метод и я использую модификатор доступа private / protected?

Ответы [ 12 ]

16 голосов
/ 10 февраля 2009

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

См. Мейерс тоже.

12 голосов
/ 11 февраля 2009

Возможно, вы путаете абстракцию с инкапсуляцией, которая понимается в более широком контексте объектной ориентации.

Инкапсуляция включает в себя все три следующих элемента:

  • Абстракция
  • Реализация скрывается
  • Отдел ответственности

Абстракция - это только один компонент инкапсуляции. В вашем примере вы абстрагировали функциональность добавления от основной части кода, в которой он когда-то находился. Вы делаете это, выявляя некоторую общность в коде - распознавая концепцию (сложение) по конкретному случаю (добавляя номер один к переменной n). Благодаря этой способности абстракция делает повторно используемый инкапсулированный компонент - метод или объект.

Не менее важной для понятия инкапсуляции является идея скрытия реализации. Вот почему инкапсуляция обсуждается в области ориентации объекта. Скрытие реализации защищает объект от его пользователей и наоборот. В OO вы делаете это, представляя интерфейс открытых методов пользователям вашего объекта, в то время как реализация объекта происходит внутри закрытых методов.

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

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

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

6 голосов
/ 10 февраля 2009

Конечно, это так.

Например, метод, который работает только с его параметрами, будет считаться «лучше инкапсулированным», чем метод, который работает с глобальными статическими данными.

Инкапсуляция была задолго до ООП:)

3 голосов
/ 10 февраля 2009

Нет, объекты не требуются для инкапсуляции. В самом широком смысле «инкапсуляция» означает просто «скрытие деталей от просмотра», и в этом отношении метод инкапсулирует детали своей реализации.

Это вовсе не значит, что вы можете сказать, что ваш код хорошо спроектирован только потому, что вы разделили его на методы. Программа, состоящая из 500 открытых методов, не намного лучше той же самой программы, реализованной одним методом из 1000 строк.

При создании программы, независимо от того, используете ли вы объектно-ориентированные методы или нет, вам нужно подумать об инкапсуляции во многих местах: скрыть детали реализации метода, скрыть данные из кода, который не требуется. знать об этом, упрощая интерфейсы для модулей и т. д.

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

Помещение кода в метод скрывает отдельные строки кода, составляющие этот метод, так что вызывающим лицам не нужно заботиться о том, что это за строки; они беспокоятся только о сигнатуре метода.

Пометка метода в классе как (скажем) «частного» скрывает этот метод, так что потребителю класса не нужно беспокоиться об этом; они беспокоятся только об открытых методах (или свойствах) вашего класса.

3 голосов
/ 10 февраля 2009

Метод - не более пример инкапсуляции, чем автомобиль - пример хорошего вождения. Инкапсуляция не о Synax, это логическая проблема дизайна. И объекты, и методы могут демонстрировать хорошую и плохую инкапсуляцию.

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

Возвращаясь к примеру с машиной: Автоматическая коробка передач обеспечивает хорошую герметизацию: как водитель, вы заботитесь о скорости движения вперед / назад. Механическая коробка передач плохая инкапсуляция: с точки зрения водителя, специальная передача, необходимая для низких / высоких скоростей, как правило, не имеет отношения к намерениям водителя.

1 голос
/ 12 октября 2009

Инкапсуляция - это процесс, в котором атрибуты (элемент данных) и поведение (функция-член) объектов, объединенных в единую сущность, называют классом.

1 голос
/ 11 февраля 2009

Давайте несколько упростим это с помощью аналогии: вы поворачиваете ключ автомобиля, и он запускается. Вы знаете, что это нечто большее, чем просто ключ, но у вас нет , чтобы знать , что там происходит . Для вас поворот ключа = запуск двигателя. Интерфейс ключа (то есть, например, вызов функции) скрывает реализацию стартера, крутящего двигатель и т. Д. (Реализацию). Это инкапсуляция. Вы избавлены от необходимости знать, что происходит под капотом, и вы счастливы за это.

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

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

1 голос
/ 10 февраля 2009

Абстрактная концепция инкапсуляции означает, что вы скрываете детали реализации. Ориентация на объект является лишь одним из примеров использования экнапсуляции. Другим примером является язык под названием module-2, в котором используются (или используются) модули реализации и определения модулей. Модули определения скрывали фактическую реализацию и, следовательно, обеспечивали инкапсуляцию.

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

[EDIT] Что касается примера в обновленном вопросе: это зависит от того, насколько узким или широким вы определяете инкапсуляцию. Ваш пример AddOne не скрывает ничего, во что я верю. Было бы скрытие / инкапсуляция информации, если бы ваша переменная была индексом массива и вы вызывали бы свой метод moveNext и, возможно, имели бы другую функцию setValue и getValue. Это позволит людям (вместе, может быть, с некоторыми другими функциями) перемещаться по вашей структуре и настройкам и получать переменные, чтобы они знали, что вы используете массив. Если ваш язык программирования будет поддерживать другие или более богатые концепции, вы можете изменить реализацию moveNext, setValue и getValue с изменением значения и интерфейса. Для меня это инкапсуляция.

1 голос
/ 10 февраля 2009

Это вещь уровня компонента

Проверьте это out:

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

(я не совсем понимаю ваш вопрос, дайте мне знать, если эта ссылка не покрывает ваши сомнения)

0 голосов
/ 23 сентября 2009

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

для пуристов ОО, которые негодуют в этом богохульстве, рассмотрите статический анонимный класс без государства и единственного метода; если функция AddOne () не является инкапсуляцией, то и этот класс не является!

и, просто чтобы быть педантичным, инкапсуляция - это форма абстракции, а не наоборот. ; -)

...