Сокрытие данных
Часть раздела Объектно-ориентированное программирование путешествия по PHP на Coddy — урок 41 из 91.
Скрытие информации — это принцип, лежащий в основе инкапсуляции: идея о том, что класс должен предоставлять только то, что необходимо, и скрывать детали своей внутренней реализации. В то время как модификаторы доступа и геттеры/сеттеры являются инструментами, скрытие информации — это философия проектирования, которая определяет, как вы их используете.
Цель состоит в том, чтобы создать четкую границу между тем, что делает класс (его публичный интерфейс), и тем, как он это делает (его внутренняя реализация). Такое разделение означает, что вы можете изменять внутренние механизмы работы, не затрагивая код, который использует этот класс:
<?php
class Temperature {
private float $celsius;
public function setCelsius(float $value): void {
$this->celsius = $value;
}
public function getCelsius(): float {
return $this->celsius;
}
public function getFahrenheit(): float {
return ($this->celsius * 9/5) + 32;
}
}
$temp = new Temperature();
$temp->setCelsius(25);
echo $temp->getCelsius() . "C = " . $temp->getFahrenheit() . "F";
Вывод:
25C = 77FКласс хранит температуру внутри в градусах Цельсия, но пользователям не обязательно об этом знать. Позже вы могли бы изменить внутреннее хранилище на Фаренгейт или Кельвин, и пока публичные методы работают так же, никакой внешний код не сломается.
Ключевой момент: Скрытие информации защищает ваш код от изменений. Скрывайте детали реализации, предоставляйте только стабильные интерфейсы, и ваши классы станет легче поддерживать и изменять со временем.
Задание
ЛегкоДавайте создадим конвертер валют, который демонстрирует сокрытие информации в действии. Вы создадите класс, который хранит деньги внутри в одной валюте, но может плавно конвертировать их в несколько валют и обратно — при этом внешний код никогда не узнает, как на самом деле хранятся данные.
Вы организуете свой код в двух файлах:
Money.php— Создайте классMoney, который внутренне хранит все суммы в центах (как целое число), чтобы избежать проблем с точностью чисел с плавающей запятой. Эта деталь реализации должна быть полностью скрыта от пользователей класса. Класс должен предоставлять:- Приватное свойство для хранения суммы в центах
setDollars(float $amount)— принимает сумму в долларах и сохраняет ее внутри как центыgetDollars()— возвращает сумму в долларах (float, 2 знака после запятой)setEuros(float $amount)— принимает евро и конвертирует в центы, используя курс: 1 EUR = 1.10 USDgetEuros()— возвращает сумму, конвертированную в евро (float, 2 знака после запятой)getInternalValue()— возвращает необработанное значение в центах (integer) для целей отладки
main.php— Подключите файл Money. Вы получите два входных значения: сумму в долларах и сумму в евро. Создайте экземплярMoney. Сначала установите сумму в долларах (преобразованную во float) и выведите три строки: значение в долларах, эквивалент в евро и внутреннее значение в центах. Затем установите сумму в евро (преобразованную во float) и снова выведите те же три значения.
Прелесть такого дизайна заключается в том, что внешний код работает со знакомыми значениями долларов и евро, совершенно не подозревая, что внутри все хранится в центах. Позже вы могли бы изменить внутреннее хранилище, чтобы использовать другую базовую валюту или другую стратегию точности, и пока публичные методы продолжают работать правильно, никакой внешний код не придется менять.
Форматируйте все выходные данные в долларах и евро ровно до 2 знаков после запятой. Каждое значение должно быть напечатано на отдельной строке, в итоге должно получиться шесть строк вывода.
Попробуйте сами
<?php
require_once 'Money.php';
// Чтение входных данных
$dollarAmount = floatval(trim(fgets(STDIN)));
$euroAmount = floatval(trim(fgets(STDIN)));
// TODO: Создать экземпляр Money
// TODO: Установить сумму в долларах и вывести:
// - Значение в долларах (2 знака после запятой)
// - Эквивалент в евро (2 знака после запятой)
// - Внутреннее значение в центах (целое число)
// TODO: Установить сумму в евро и вывести:
// - Значение в долларах (2 знака после запятой)
// - Эквивалент в евро (2 знака после запятой)
// - Внутреннее значение в центах (целое число)
?>В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово $thisМетодыСвойстваКонструктор (__construct)Деструктор (__destruct)Итоги — Простой калькулятор4Наследование
Основы наследованияКлючевое слово parent::Переопределение методовКлючевое слово finalАбстрактные классыИтоги — Иерархия сотрудников7Инкапсуляция
Public, Protected, PrivateПодробный разбор модификаторов доступаГеттеры и сеттерыСокрытие данныхConstructor Promotion (8.0)Итоги — Система учета студентов10Продвинутые концепции ООП
Композиция против наследованияВнедрение зависимостейАнонимные классыПеречисления (PHP 8.1)Файберы (PHP 8.1)Глубокое погружение в клонирование объектовГенераторы и итераторы13Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикПаттерн Репозиторий2Пространства имен и автозагрузка
Введение в пространства именКлючевое слово useСтандарт автозагрузки PSR-4Автозагрузчик ComposerИтоги: структурированный проект5Интерфейсы и контракты
Введение в интерфейсыРеализация интерфейсовРеализация нескольких интерфейсовИнтерфейс против абстрактного классаType Hinting с интерфейсамиИтоги — Калькулятор фигур8Магические методы
Введение в магические методы__toString и __debugInfo__get, __set, __isset, __unset__call и __callStatic__clone и клонирование объектов__serialize и __unserializeИтоги — Кастомная коллекция11Система типов и обработка ошибок
Объявление типовNullable-типыТипы объединения и пересеченияКлассы исключенийИерархия пользовательских исключенийTry, Catch, FinallyИтоги — Валидатор форм14Проект: Управление библиотекой
Обзор проектаКлассы Book и User3Свойства классов
Свойства экземпляра и статические свойстваКонстанты в классахСтатические методы и свойстваПриватные и защищенные свойстваСвойства Readonly (PHP 8.1)Итоги — Менеджер банковского счета6Полиморфизм
Снова о переопределении методовПолиморфизм через интерфейсыType Hinting и Union TypesПозднее статическое связываниеИтоги — Payment Processor9Трейты
Введение в трейтыИспользование нескольких трейтовРазрешение конфликтов трейтовАбстрактные методы в трейтахТрейты и наследование12Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonПаттерн FactoryПаттерн ObserverПаттерн Strategy