使用自定义提供程序类来消除紧耦合 [英] Using a custom provider class to remove tight coupling

查看:116
本文介绍了使用自定义提供程序类来消除紧耦合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义框架,我有一个类/方法,它使用我自己的缓存类。



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

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

我想要删除紧耦合,但实际上我有点



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



要开始我有 HHConfig 定义缓存类的 static 属性。简而言之:

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

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

 界面IHHServiceProvider 
{
public function getService();
}

然后我有另一个类实现这个 / code>。

 类HHCacheProvider实现IHHServiceProvider 
{
public static function getService()
{
$ class = HHConfig :: $ _ cacheClass;
return new $ class();
}
}

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

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

我的 IHHServiceProvider isn真的很像典型的 Provider 类,因为你不能真正注册任何服务。它只是在 HHConfig 类中查找加载和返回的类。



所以不知何故,这种方法对我来说感觉不对,但我认为它显示了我想要实现的。我可以通过哪种方式改善这一点?






请注意我不是在寻找一个简单的依赖注入模式。因为我不想为每个构造函数类注入我的 Cache 类。我需要一种 的方法。



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

解决方案


注意:提供者无关。没有这个名字的模式。


而不是制作一些神奇的privider,你应该看看工厂模式。基本上这个想法是:


  1. 您将在使用某些服务的类中注入工厂(假设缓存不是您打算的唯一形式的服务。)


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

}

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



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



..和几个您可能会发现有价值的讲座:




I have a custom framework where i have a class/method which uses my own Cache class.

Currently it is tightly coupled. So a method instantiates the Cache class like this:

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

I want ro remove the tight coupling but that's actually where i'm a bit stuck.

I thought it would be a good idea to create some sort of ServiceProvider class. But i'm not sure if this is really the right approach.

To start i have HHConfig file which has a static property in which a cache class is defined. In short:

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

So basically i have a class like this, which is part of the Core functionality of my framework:

interface IHHServiceProvider
{
    public function getService ( );
}

Then i have another class which implements this interface.

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

So now someMethod can use the HHCacheProvider class to get an instance of a Cache class.

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

My IHHServiceProvider isn't really like the typical Provider class since you can't really register any Services to it. It simply looks in the HHConfig class what "class" to load and returns in instance of that.

So somehow this method doesn't feel right to me, but i do think it shows what i want to achieve. In what ways can i improve this?


Please note that i'm not looking for a simple Dependency Injection pattern for this. Because i don't want to inject my Cache class to every constructors class. I need a non tight coupling way of getting an instance of the HHCache class somehow from within a method.

Some sort of provider class that can be part of my framework seems like the right direction.

解决方案

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

Instead of making some magical "privider", you should take a look at factory pattern. Basically the idea is a follows:

  1. You inject a factory in classes that will use some services (assuming that Cache is not the only form of service that you aim for).

  2. The class request from factory the service that it needs:

    • if service has been already initialized once, it just returns an instance to your
    • else it creates new instance, stores it and returns you to "consumer"

The simplest code example would be something like this:

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

}

This is an extremely simplified example, but even in this case, if you inject an instance of this factory in any number of objects, they all will have access to same pool of instances.

If you ever decide to look into concept of DI Containers, then factories are also the place where it is appropriate to utilize them, without degrading them to as service locator anti-pattern.

.. and few lectures that you might find valuable:

这篇关于使用自定义提供程序类来消除紧耦合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆