Menu
Coddy logo textTech

Сокрытие данных

Часть раздела Объектно-ориентированное программирование путешествия по 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

Класс хранит температуру внутри в градусах Цельсия, но пользователям не обязательно об этом знать. Позже вы могли бы изменить внутреннее хранилище на Фаренгейт или Кельвин, и пока публичные методы работают так же, никакой внешний код не сломается.

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

challenge icon

Задание

Легко

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

Вы организуете свой код в двух файлах:

  • Money.php — Создайте класс Money, который внутренне хранит все суммы в центах (как целое число), чтобы избежать проблем с точностью чисел с плавающей запятой. Эта деталь реализации должна быть полностью скрыта от пользователей класса. Класс должен предоставлять:
    • Приватное свойство для хранения суммы в центах
    • setDollars(float $amount) — принимает сумму в долларах и сохраняет ее внутри как центы
    • getDollars() — возвращает сумму в долларах (float, 2 знака после запятой)
    • setEuros(float $amount) — принимает евро и конвертирует в центы, используя курс: 1 EUR = 1.10 USD
    • getEuros() — возвращает сумму, конвертированную в евро (float, 2 знака после запятой)
    • getInternalValue() — возвращает необработанное значение в центах (integer) для целей отладки
  • main.php — Подключите файл Money. Вы получите два входных значения: сумму в долларах и сумму в евро. Создайте экземпляр Money. Сначала установите сумму в долларах (преобразованную во float) и выведите три строки: значение в долларах, эквивалент в евро и внутреннее значение в центах. Затем установите сумму в евро (преобразованную во float) и снова выведите те же три значения.

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

Форматируйте все выходные данные в долларах и евро ровно до 2 знаков после запятой. Каждое значение должно быть напечатано на отдельной строке, в итоге должно получиться шесть строк вывода.

Шпаргалка

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

Пример скрытия информации с классом Temperature:

<?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

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

Основные преимущества: Скрытие информации защищает код от изменений. Скрывая детали реализации и предоставляя только стабильные интерфейсы, классы становятся проще в обслуживании и модификации с течением времени.

Попробуйте сами

<?php

require_once 'Money.php';

// Чтение входных данных
$dollarAmount = floatval(trim(fgets(STDIN)));
$euroAmount = floatval(trim(fgets(STDIN)));

// TODO: Создать экземпляр Money

// TODO: Установить сумму в долларах и вывести:
// - Значение в долларах (2 знака после запятой)
// - Эквивалент в евро (2 знака после запятой)
// - Внутреннее значение в центах (целое число)

// TODO: Установить сумму в евро и вывести:
// - Значение в долларах (2 знака после запятой)
// - Эквивалент в евро (2 знака после запятой)
// - Внутреннее значение в центах (целое число)

?>
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование