我在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”,我知道它的错误。
您如何建议解决此问题?
答案 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
传递到您需要缓存的位置。
根据经验:良好的设计不需要CacheInterface
或extends
。 oop初学者,也有一些高级编码员认为,oop非常酷,并且可以通过扩展大量的类来重用他们的代码。了解abstract
和extends
并不意味着您必须在可能的情况下使用它们。
//编辑:你问了2个问题而且我忽略了第一个问题。检查DI(依赖注入)作为创建模式。