PANOV_DEV
@PANOV_DEV

Нужно ли использовать interface?

Есть класс ValutaManager в __construct у меня добавление объектов:
class ValutaManager {
   private $valuta = [];

   public function __construct() {
      $this->valuta["rub"] = new RubMoney();
      $this->valuta["uah"] = new UahMoney();
      $this->valuta["eur"] = new EurMoney();
   }
}

Так же, во всех этих классах (RubMoney, UahMoney, EurMoney) у меня имеется метод getName() - он возвращает мне название валюты.

Так же, у меня сам метод getName() вызывается в ValutaManager.

Нужно ли создавать interface Money и указывать его в каждом классе Uah, Rub, Eur?

Можно ведь его не указывать и будет работать так же, как и запланировано.
  • Вопрос задан
  • 215 просмотров
Пригласить эксперта
Ответы на вопрос 3
ipatiev
@ipatiev Куратор тега PHP
Потомок старинного рода Ипатьевых-Колотитьевых
Нет, ничего указывать не надо.
Тут и без интерфейсов получатся отличные самолёты из соломы и палок.
Ответ написан
Newto
@Newto
Интерфейсы используются для структуризации вашего кода. Не потому что надо, а потому что это вносит порядок в разработку. Вы можете не использовать интерфейс и тогда в каждом вашем классе можно будет делать всё что угодно. А можно использовать интерфейс, тем самым обязывая соблюдать определённые правила структуры. Даже один разработчик придумав некую структуру кода сегодня, может забыть/забить на неё через какое-то время, а если их несколько, то тем более, тем самым превращая программу в бардак. В общем это вопрос порядка, а не обязательности.
Ответ написан
gzhegow
@gzhegow
aka "ОбнимиБизнесмена"
Вы когда на работу устраиваетесь - заключаете контракт. Контракт описывает что вы должны уметь. Это вот интерфейс "на вас".
Тогда как вы сами - это "класс", который что-то уже умеет.

Если ваши классы ничего ЧТО ТРЕБУЕТСЯ ДРУГИМ не делают - интерфейс на них не обязателен.

Интерфейс выполняет две задачи. Даёт классу назначение (имя в рамках задачи) и контроллирует, что класс что-то умеет.

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

Назначение чаще всего применяется в контейнерах зависимостей (см. Psr\ContainerInterface), там два интерфейса можно (и нужно) использовать, чтобы два одинаковых объекта положить в разные "коробки" и достать одну в одном классе, а другую - в другом.

Вторая функция применяется для проверки входных данных, когда вы в функции указываете тип данных для параметра, и программа упадет в ошибку, если тип данных неверный. Этот же принцип используется для организации ПОДМЕНЫ одного класса на другой. Если смотреть на вашу задачу (хотя здесь интерфейс не нужен) , то вместо того, чтобы на входе писать RurMoney вы сможете написать MoneyInterface, если вам не важно, какая валюта придет в функцию, но они все умеют в ваш ->getName()

В некоторых программах есть классы-данные, в которых нет методов (либо есть только геттеры и сеттеры - это вот ваш случай). Эти классы называют ValueObject. Для них интерфейс писать не надо. Чаще всего для них даже несколько классов делать не надо, просто один класс с разными свойствами. Но вот если методы есть - то нужно сделать АБСТРАКТНЫЙ КЛАСС, от него наследовать конкретные классы, тогда на входе проверять не интерфейс, а абстрактный класс. Абстрактный класс объединяет в себе "действия по-умолчанию" и "проверку умения" (через абстрактные методы). Они похожи на те, что в вашей задаче - getName() есть у всех - отличный способ положить этот метод в абстракцию, и не писать интерфейс, т.к. у вас уже есть абстрактный класс.

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

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

Конкретно вашу задачу лучше решать разобравшись как настраивать вот этот пакет:
https://github.com/moneyphp/money
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы