3

我有一个自定义框架,其中我有一个使用我自己的Cache类的类/方法。

目前它是紧密耦合的。所以一个方法实例化这个Cache类是这样的:

public function someMethod ( )
{
    $cache = new Cache\HHCache();
}

我想删除紧密耦合,但这实际上是我有点卡住的地方。

我认为创建某种形式是个好主意ServiceProvider类是个好主意。但我不确定这是否真的是正确的方法。

首先,我有HHConfig一个文件,该文件具有static定义缓存类的属性。简而言之:

class HHConfig
{
    static $_cacheClass = '\Core\Cache\HHCache';
}

所以基本上我有一个像这样的类,它是我框架核心功能的一部分:

interface IHHServiceProvider
{
    public function getService ( );
}

然后我有另一个实现这个的类interface

class HHCacheProvider implements IHHServiceProvider
{
    public static function getService ( )
    {
        $class = HHConfig::$_cacheClass;
        return new $class();
    }
}

所以现在someMethod可以使用HHCacheProvider类来获取一个Cache类的实例。

public function someMethod ( )
{
    $cache = HHCacheProvider::getService ( );
}

我的课程IHHServiceProvider不像典型的Provider课程,因为您无法真正注册任何课程Services。它只是看起来在HHConfig类中查找要加载的“类”并在该实例中返回。

所以不知何故,这种方法对我来说并不合适,但我确实认为它显示了我想要实现的目标。我可以通过哪些方式改进这一点?


请注意,我不是为此寻找一个简单的依赖注入模式。因为我不想将我的Cache类注入到每个构造函数类中。我需要一种非紧密耦合方式来获取HHCache的方式来以某种方式从

可以成为我框架一部分的某种提供程序类似乎是正确的方向。

4

2 回答 2

2

注意: “提供者”没有任何意义。没有那个名字的模式。

与其制作一些神奇的“privider”,不如看看工厂模式。基本上这个想法如下:

  1. 您在将使用某些服务的类中注入一个工厂(假设这Cache不是您想要的唯一服务形式)。

  2. 来自工厂的类请求它需要的服务:

    • if服务已经初始化一次,它只是返回一个实例给你
    • else它创建新实例,存储它并将您返回给“消费者”

最简单的代码示例是这样的:

class ServiceFactory
{
    private $storage = [];

    public function create( $name )
    {
        if ( false === array_key_exists( $name, $this->storage ))
        {
            $instance = new $name;
            $this->storage[$name] = $instance;
        }

        return $this->storage[$name];
    }

}

这是一个极其简化的示例,但即使在这种情况下,如果您在任意数量的对象中注入此工厂的实例,它们都将可以访问相同的实例池。

如果您决定研究DI Containers的概念,那么工厂也是适合使用它们的地方,而不会将它们降级为服务定位器反模式。

..以及一些您可能会觉得有价值的讲座:

于 2013-04-11T21:43:26.860 回答
1

根据 OP 要求

特别是因为它将成为框架的一部分,您应该注入缓存。DI Container 是这里最好的解决方案,您可以将实际的 Cache 实现配置为单例。您提出的解决方案与某些服务紧密耦合,很难单独测试。实际上,它看起来更像是一种服务定位器模式,而不是提供者。

如果您使用的工厂不会替换 DI 容器。DI 的要点是代码不应耦合到外部静态服务。除非您有充分的理由,否则任何对象都应仅使用注入的(通过构造函数或作为方法参数)依赖项。

于 2013-04-11T08:57:17.873 回答