Инкапсуляция
Прежде чем переходить к инкапсуляции давай поговорим про то, как можем получать доступ к нашим атрибутам из вне. Возьмем тот же класс Person
:
По сути мы написали обычные методы-обертки для каждого нашего атрибута для того, чтобы менять или получать значения конкретных атрибутов.
Метод, который позволяет получать значение атрибута называется обычно Getter
, а метод, который позволяет изменять это значение, называется Setter
.
Ruby позволяем нам сильно сократить за счет attribute accessors
. Существует 3 типа аксессоров:
attr_reader
- создает невидимый метод для чтения атрибутаattr_writer
- создает невидимый метод для записи атрибутаattr_accessor
- создает невидимые методы записи и чтения атрибута
Давайте посмотрим как может выглядеть наш класс Person
с использованием аксессоров:
Как мы видим количество написанного кода внутри нашего класса Person
заметно снизилось.
А при чем тут инкапсуляция ? Инкапсуляция - это принцип ООП, который заставляет нас уберегать наши объекты от нежелательного воздействия из вне. Не всегда нам нужна возможность менять наш класс снаружи как угодно, иногда это может сломать нашу логику или затруднить использование нашего кода для посторонних разработчиков. Возьмем к примеру объект из реальной жизни. Нужно ли нам давать пользователю знать о внутренностях автомобиля для того, чтобы пользователь начал ездить на этой машине ? Нет, пользователь должен знать как ездить на машине, а не как она устроена, для этого производители машин скрывают от пользователя реализацию автомобиля. В программировании это работает точно также. Нам не нужно давать пользователю все возможности для работы с нашим объектом, если конечная цель использования с этим не связана.
Для того, чтобы в ruby защитить наш объект от нежелательного использования у нас есть такие инструменты как: attribute accessors
, а также приватные методы и публичные.
Публичные методы - это методы, которыми мы можем пользоваться снаружи класса, вызывая их у объектов этих классов. Методы которые мы рассматривали раньше были публичными.
Приватные методы - это методы, которыми мы можем пользоваться только внутри нашего класса, вызывая их из других методов, например. Обычно приватные методы создают, если нам нужно в разных публичных методах переиспользовать один и тот же кусок кода, а также для разбиения большого методы на более мелкие. Это позволяет снизить сложность прочтения кода вашего приложения.
Возможно по началу будет тяжело в этом ориентироваться, но если каждый раз задавать вопрос себе А нужен ли публичный доступ для данного метода ?
или А нужен ли acessor для изменения атрибута ? Не сломает ли он нашу программу, если пользователь захочет напрямую изменить его ?
.
Инкапсуляция помогает сделать код более безопасным и уменьшить количество взаимодействия между объектами, снижая риск возникновения ошибок в ходе работы.
Часто можно услышать такое понятие как API
и многие ошибочно считают, что это касается только сетевого взаимодействия, но API
и инкапсуляция тесно между собой связаны. API
- это итоговая реализация инкапсуляции нашей программы, которая выстраивает все способы взаимодейсвия с нашей программы. Сам Ruby тоже предоставляем нам API
для разработки программ. Взять тот же String
. Что такое строка для компьютера ? Это всего лишь набор байтов доступ к которым Ruby нам не дает. Вместо этого мы получаем набор методов для взаимодейсвия с нашей строкой, а также публичные доступы до определенных переменных на чтение, которые позволяют получить полезную информацию о нашей строке.
Задание animals
Внимание ! Это и последующие задания данного модуля с названием animals
необходимо выполнять в одной и той же директории в корне модуля - 3_oop/animals
выставьте для вашего класса
Cat
те права доступа и акссесоры, которые по вашему мнению большего всего подходят.Реализуйте логику подсчета суммарно съеденной еды, а также счетчик суммарно выпитой воды.
создайте экземпляр класса кота и 'замяйкайте' его до сметри.
создайте еще одие экзампляр класса кота и перекормите его до смерти.
Задание elevator
Создайте класс Elevator, эмулирующий работу пассажирского лифта. В классе создайте:
Переменные
current_floor
(текущий этаж),min_floor
иmax_floor
(минимальный и максимальный этажи).Конструктор с двумя параметрами
min_floor
иmax_floor
, сохраняющий эти параметры в соответствующих переменных класса.Значение переменной
current_floor
изначально должно быть равно 1.Метод
get_current_floor
, возвращающий текущий этаж, на котором находится лифт.Метод
move_down
, перемещающий лифт на один этаж вниз (уменьшающий значение переменнойcurrent_floor
на единицу).Метод
move_up
, перемещающий лифт на один этаж вверх.Метод
move(floor)
, перемещающий лифт на заданный в параметре этаж, если он задан верно. Если параметр у метода задан неверно, ничего не делать и выводить в консоль сообщение об ошибке. Этот метод может перемещать лифт только последовательно, по одному этажу, с помощью циклов и методовmove_up
иmove_down
, и он должен выводить в консоль текущий этаж после каждого перемещения между этажами.
Этот код поможет вам протестировать созданный класс Elevator: он будет создавать лифт и в консоли запрашивать этаж, на который нужно переместить лифт, после чего вызывать у него метод move с указанием полученного из консоли этажа. Запустите получившийся код и убедитесь, что он работает корректно.
Дополнительный материал
Last updated