Интерфейс конфликтует с PHP Pimple

У меня есть собственный класс, который расширяет Pimple\Container. Идея заключалась в том, чтобы обернуть, на мой взгляд, уродливые методы доступа к определенным службам (см. Ниже):

offsetGet($key)       -> get($key)
offsetSet($key, $val) -> set($key, $val)
offsetExists($key)    -> has($key)

Эта идея отлично работала для того, что я хотел сделать. Затем я продолжил создавать класс Application, который я выбрал INHERITANCE, а не AGGREGATION, не по какой-то конкретной причине, кроме того, что казалось бы логикой.

Теперь проблема в том, что у меня есть ServiceProvider, который принимает экземпляр приложения вместо Pimple \ Container, так как я создал свой собственный ServiceProviderInterface, который определяет этот контракт.

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

Я думал, что принцип интеграции интерфейса спасет мой день, но я не уверен.

  1. Мог ли я нарушить Принцип замещения Liskorv здесь, предположив, что Приложение расширяет отношения Pimple \ Container?

  2. Могу ли я использовать свой собственный интерфейс, чтобы зарегистрировать своих поставщиков услуг с ошибкой в ​​том, что любая передаваемая мной услуга не соответствует контракту pimple\ServiceProvider?

Проще говоря, возможно ли расширить контейнер Pimple и игнорировать поставщика услуг библиотеки и использовать ваш, который определяет тот же контракт, но с другим параметром?

1 ответ

Прежде всего,

Идея заключалась в том, чтобы обернуть, на мой взгляд, уродливые методы доступа к определенным услугам

Уродливые методы из ArrayAcess интерфейс, который позволяет вам получить доступ к свойствам в виде массива:

$container = new Pimple();
$container['session_storage'] = function ($c) {
    return new SessionStorage('SESSION_ID');
};

$container['session'] = function ($c) {
    return new Session($c['session_storage']);
};

Затем я продолжил создавать класс Application, который я выбрал INHERITANCE, а не AGGREGATION, не по какой-то конкретной причине, кроме того, что казалось бы логикой

Это просто неправильно. Вы всегда должны выбирать Агрегацию, а не Наследование, когда это возможно.

Наследование - это статически тесно связанные отношения, и оно ограничено только одним в PHP. Вы не можете изменить наследование во время выполнения.

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

Теперь проблема в том, что у меня есть ServiceProvider, который принимает экземпляр приложения вместо Pimple\Container, так как я создал свой собственный ServiceProviderInterface, который определяет этот контракт.

Это не имеет никакого смысла! Почему ваш поставщик услуг зависит от вашего приложения? Не должно ли быть наоборот? Поставщик является автономным модулем. Ваше приложение имеет несколько зависимостей.

О ваших вопросах,

  1. Лучший способ узнать, нарушили ли вы LSP, это спросить себя:
    Могу ли я заменить Container объект для Application объект без каких-либо потерь в функциональности?

  2. Nop. Интерфейсы - это контракты, и контракты должны соблюдаться.

Другие вопросы по тегам