抽象,接口和设计模式

时间:2015-09-22 20:12:55

标签: php design-patterns

我在PHP中开发了很多年,使用PHP 5中的小型自制MVC框架,从未使用过PHP 5.2+的优势。

我知道什么是抽象类,接口,知道命名空间,以及一些设计模式,但总是在一个简单的事情中,更好地使用接口,抽象类或模式设计。

在我的框架中,我有一个Core with Router类,Router调用Core,Core加载Controller并使用Router vars调用控制器功能。

Controller扩展了Core,并且可以使用Core中的一个函数来加载“组件”,这个函数是一个简单的单例模式,使用静态数组来实例化我从控制器或其他组件“调用”的类,这是非常快,使用低内存,但有更好的方法。

在控制器或组件中,我写道:

function example() {

    $this->loadComponent(array('Cache', 'Template', 'Email'));
    $this->Email->X();

}

这创建实例(如果不存在,如果存在则返回指针“&amp;”实例,而不是副本)并设置为控制器或组件以允许使用$ this-&gt; ComponentName-&gt; XXXX < / p>

该函数使用$ this-&gt; loadComponent(array('Cache'=&gt;'Cache2'))创建副本;如果我需要一些副本而不是相同的。 (例如,对于多个DB连接)

我认为这可以做得更好。

现在我陷入了另一个设计问题:

我有一个Cache类,这个类有3种缓存方式,Memcache,Redis或File Cache。

这是一个简单的类(没有抽象或接口),并且缓存函数在分离的类CacheMem,CacheRes,CacheFile中,当使用loadComponent加载Cache类时,该类读取一个define config,并使用此定义执行此操作:

function __construct() {

    private $engine;

    switch (CONFIG_CACHE_TYPE) {

        case "MEM":
        $class = 'CacheMem'
        require ('Components'.DS.$class.'.php');
        $this->engine = new CacheMem();

        break;

        case "RES":
        $class = 'CacheRedis'
        require ('Components'.DS.$class.'.php');
        $this->engine = new CacheRedis();

        break;

        default:
        $class = 'CacheFile';
        require ('Components'.DS.$class.'.php');
        $this->engine = new Cachefile();
        break;

    }

}

function read($key) {
    $this->engine->read($key);
}

function write($key, $value, $time=3800) {
    $this->engine->write($key, $value, $time=3800);
}

有更好的解决方法吗?这是一个简单的简单问题,但我陷入了一件事:我需要使用“Cache”名称加载缓存类而不是CacheMem,CacheFile或CacheRes?

我尝试使用抽象类Cache,并使用Mem,Res或File扩展,但我需要在Cache类中实例化子项,因为我想使用“Cache”而不是“CacheXXX”,我知道它的错误。

您如何建议解决此问题?

1 个答案:

答案 0 :(得分:0)

有很多方法可以解决问题:)。

  

Controler扩展了Core,可以使用Core中的一个函数

如果您不知道是否延长课程,请问自己:控制器是核心吗?希望它不是。如果你的控制器需要一个核心,那么在构造函数中传递它。原因是1.隐藏实施,意味着注入&#39;核心和使用是隐藏在控制器上的核心访问,2。只允许一个扩展,所以仔细和智能地使用它,例如汽车或自行车是一种车辆,因此延伸可能没问题,如果我们的车辆有一些实施汽车和自行车使用,但也许车辆只是一个没有实施的接口。

  

这创建实例(如果不存在,如果存在则返回指针&#34;&amp;&#34; tho the instance,而不是副本)

PHP正在使用引用计数变量。返回一个对象意味着返回引用。要复制对象,PHP中有nil运算符。

  

切换(CONFIG_CACHE_TYPE)

什么是clone?如果它是在调用构造之前定义的const,那么这是一个坏主意。只需将其作为变量传递。请记住,您使用的某些开关案例违反了开放式封闭原则,这是一种糟糕的设计。

CONFIG_CACHE_TYPE

在您的特殊情况下,我将创建一个接口CacheInterface,让您的类实现switch(...) { case ...: ... = new A(); case ...: ... = new B(); case ...: ... = new C(); ... } read,然后只需将write传递到您需要缓存的位置。

根据经验:良好的设计不需要CacheInterfaceextends。 oop初学者,也有一些高级编码员认为,oop非常酷,并且可以通过扩展大量的类来重用他们的代码。了解abstractextends并不意味着您必须在可能的情况下使用它们。

//编辑:你问了2个问题而且我忽略了第一个问题。检查DI(依赖注入)作为创建模式。