提问人:Pekka 提问时间:3/11/2010 最后编辑:Pekka 更新时间:3/11/2010 访问量:292
可以选择自定义类,但可以选择统一的类名
Having the option of customized classes but a unified class name
问:
假设您正在构建一个 Web 应用程序,该应用程序有一天会成为一个打包的产品,用户希望能够扩展和自定义它。
它带有一个核心库,由包含类的 PHP 文件组成:
/library/
/library/frontend.class.php
/library/filesystem.class.php
/library/backend.class.php
现在,假设您希望保留用户无法修补的干净核心。不过,您希望用户能够根据需要自定义每个螺母和螺栓。
我目前的想法是创建一个自动加载机制,当一个类被实例化时,首先加载核心包括:
/library/frontend.class.php
然后,它切换到目录并查看是否存在同名的 include:user
/user/library/frontend.class.php
如果存在,它也包括它。
显然,用户 include 必须包含一个类定义,该类定义扩展了核心包含中的定义。
现在我的问题是,我将如何实例化这样的类?毕竟,我始终可以确定有一个定义:
class frontend_core
但我不能确定有没有一个
class frontend_user extends frontend_core
但是,我希望能够依赖并实例化一个类名,而不管该类是否有自定义扩展。
有没有一种聪明的方法、想法或模式来实现这一目标?
当然,我可以编写一个简单的工厂帮助函数,首先查找类,然后查找类并返回一个初始化的对象,但我真的希望尽可能保持干净和简单,因为正如我所说,它将是一个打包的产品。user
core
我正在寻找一种聪明的技巧或模式,它使用尽可能少的代码,并引入尽可能少的新功能。
答:
我会在核心中实现钩子,这样用户就不必破解核心,但仍然可以使用钩子扩展核心
评论
你为什么不遵循 Propel 使用的方法呢?生成基类,并且已经提供了一个空的 User 类(扩展基类),用户可以在其中放置其重写/特定的实现详细信息,并且在代码中始终引用 User 类。所以基本上你只是使用你所描述的逻辑的反面。
如果上面的解释不清楚,请查看 http://propel.phpdb.org/trac/wiki/Users/Documentation/1.4/QuickStart#a6.UsingtheGeneratedSQLandOMFiles 并为小型数据库生成代码。基类位于 om 文件夹中,(默认为空)用户类位于根文件夹中。
评论
我认为当您也想使用继承时,使用单个文件名会更复杂。基本上必须知道在哪里可以找到这两个类。两者都必须包括在内。class user_frontend extends core_frontend
如果你只是想这样做,你可以使用 PHP5.3 的 class_alias
将 Frontend 指向要使用的主类。低于 5.3。你可以使用ServiceFinder,它知道如何将服务名称映射到类,然后使用或使用依赖注入框架获取前端。new Frontend
$service->get('frontend')
编辑 我删除了之前给出的 Loader 代码,因为它正遭受这个问题的困扰。
我会使用核心类的构造函数来确定要加载的用户类,然后在核心类中实现工厂方法来生成用户类的实例。通过保护用户类的构造函数,并让用户类扩展核心类,可以确保其他位置的代码无法实例化用户类。
C.
你可以有一个加载器类来决定实例化哪个类:
Loader::instance()->load('Frontend')
上一个:正则表达式可匹配无限数量的选项
评论