2

我有一个扩展 Pimple\Container 的自定义类。在我看来,这个想法是包装用于访问已定义服务的丑陋方法(见下文):

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

这个想法很适合我想做的事情。然后我继续创建一个应用程序类,我选择继承而不是聚合不是出于任何特定原因,而不是看起来是逻辑。

现在的问题是当我有一个接受应用程序实例而不是 Pimple\Container 的 ServiceProvider 时,因为我创建了自己的定义此合同的 ServiceProviderInterface。

我现在意识到假设 Application 曾经并且仍然是一种 Container 并让它使用与父类不同类型的合同并不是一个好主意。但是,在我看来,从概念上讲,应用程序实例是某种容器,因为在其中我存储了一些键 => 值对数据。

我在想接口隔离原则会节省我的时间,但我不确定。

  1. 我对应用程序扩展 Pimple\Container 关系的假设是否违反了 Liskorv 替换原则?

  2. 有什么办法可以使用我自己的接口来注册我的服务提供者,因为我通过的任何服务都不符合 pimple\ServiceProvider 合同的错误?

简而言之,是否可以扩展 Pimple 的容器并忽略图书馆的服务提供者并使用定义相同合同但参数不同的您?

4

1 回答 1

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']);
};

然后我继续创建一个应用程序类,我选择继承而不是聚合不是出于任何特定原因,而不是看起来是逻辑

这是错误的。如果可能,您应该始终选择聚合而不是继承。

继承是一种静态的紧耦合关系,它仅限于 PHP 中的一种。您不能在运行时更改继承。

另一方面,组合是动态的,如果按照 SOLID 原则实施,可能会丢失耦合。使用组合时,您可以在运行时完美地切换关系。

现在的问题是当我有一个接受应用程序实例而不是 Pimple\Container 的 ServiceProvider 时,因为我创建了自己的定义此合同的 ServiceProviderInterface。

这没有任何意义!为什么您的服务提供商会依赖您的应用程序?不应该反过来吗?提供者是一个独立的模块。您的应用程序有几个依赖项。

关于你的问题,

  1. 了解您是否违反 LSP 的最好方法是问自己:
    我可以用一个Container对象替换一个Application对象而不损失任何功能吗?

  2. 没有。接口是契约,契约应该被遵守。

于 2016-07-20T21:02:49.110 回答