php - 使用自定义提供程序类来消除紧耦合

标签 php oop design-patterns

我有一个自定义框架,其中有一个使用我自己的 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 类中查找要加载的“类”并在其实例中返回。

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


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

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

最佳答案

Note: "provider" means nothing. There is not pattern by that name.

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

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

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

    • 如果服务已经初始化过一次,它只是返回一个实例给你
    • 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];
    }

}

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

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

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

关于php - 使用自定义提供程序类来消除紧耦合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15926737/

相关文章:

c# - 如何控制急切加载数据映射器的获取深度?

java - 我该如何改进这段代码?

php - 使用 Symfony/Doctrine 的 Memcache 正在重新加载数据

php - 如何将我的 Controller 移动到 Laravel 5.2 中的单独包文件夹中?

c++ - 在显示对象时获取垃圾值

oop - 如何实现功能共享相同逻辑的接口(interface)?

php - 商业智能时间机器 (PHP/MySQL)

php - 如何解决对php中非对象的成员函数query()的调用?

php - 如何(以及在​​哪里)在 Laravel 中注册自定义查询方法

php - 重构返回不同数据类型的函数