我有一个自定义框架,其中有一个使用我自己的 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 类的实例。

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

最佳答案



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

  • 您在将使用某些服务的类中注入(inject)一个工厂(假设 Cache 不是您所针对的唯一服务形式)。
  • 类从工厂请求它需要的服务:
  • 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];
        }
    
    }
    

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

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

    .. 以及一些您可能会觉得有值(value)的讲座:
  • The Clean Code Talks - Don't Look For Things!
  • The Clean Code Talks - Global State and Singletons
  • 关于php - 使用自定义提供程序类来消除紧耦合,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15926737/

    10-16 20:38