【问题标题】:Having the option of customized classes but a unified class name可以选择自定义类但统一类名
【发布时间】:2010-03-11 13:05:57
【问题描述】:

假设您正在构建一个 Web 应用程序,该应用程序有一天会成为一个打包产品,用户希望能够扩展和自定义一个产品。

它带有一个核心库,由包含类的 PHP 文件组成:

/library/
/library/frontend.class.php
/library/filesystem.class.php
/library/backend.class.php

现在,假设您想保留一个用户无法修补的干净的核心。不过,如果需要,您希望用户能够自定义每个螺母和螺栓。

我目前的想法是创建一个自动加载机制,当一个类被实例化时,首先加载核心包括:

/library/frontend.class.php

然后,它切换到user 目录并查看是否有同名的包含:

 /user/library/frontend.class.php

如果存在,它也包括它。

显然,用户包含必须包含扩展核心包含中定义的类定义。

现在我的问题是,我将如何实例化这样的类?毕竟,我总能确定有以下定义:

class frontend_core

但我不能确定是否存在

class frontend_user extends frontend_core

但是,我希望能够依赖并实例化一个类名,无论该类是否有自定义扩展。

有没有聪明的方法、想法或模式来实现这一目标?

当然,我可以编写一个简单的工厂辅助函数,它首先查找 user 类,然后查找 core 类并返回一个初始化的对象,但我真的希望保持这种简洁和简单可能,因为正如我所说,它将是一个包装产品。

我正在寻找一种使用尽可能少的代码并尽可能少引入新功能的巧妙技巧或模式。

【问题讨论】:

    标签: php oop


    【解决方案1】:

    您为什么不遵循 Propel 使用的方法?您生成基类并且已经提供了一个空的 User 类(扩展基类),您的用户可以在其中放置他们的覆盖/特定实现细节,并且在您的代码中您始终引用 User 类。所以基本上你只是使用你描述的逻辑的反面。

    如果上面的解释不清楚,请查看http://propel.phpdb.org/trac/wiki/Users/Documentation/1.4/QuickStart#a6.UsingtheGeneratedSQLandOMFiles 并为小型数据库生成代码。基类位于 om 文件夹中,(默认为空)用户类位于根文件夹中。

    【讨论】:

    • 如果没有自定义项,我想将用户目录保持为空,但另一方面,这是个好主意。它为用户提供了简单的入门点,甚至可能在空类文件中提供代码示例和解释。我会考虑的。
    • 但是当用户不使用它时,它也会添加多余的类来加载,例如当用户选择使用默认值时,User_Frontend 加上 Core_Frontend 而不仅仅是 Core_Frontend。
    【解决方案2】:

    我会在核心中实现挂钩,因此用户不必破解核心,但仍然可以使用挂钩扩展核心

    【讨论】:

    • @streetparade 我已经在应用程序的各个地方使用了挂钩系统。对于更深入的定制,仍然需要覆盖或扩展核心类。我想提供两种可能性。
    【解决方案3】:

    我会使用核心类的构造函数来确定要加载的用户类,然后在核心类中实现一个工厂方法来生成用户类的实例。通过保护用户类的构造函数,并让用户类扩展核心类,您可以确保其他地方的代码无法实例化用户类。

    C.

    【讨论】:

      【解决方案4】:

      我认为当您还想使用继承时,使用单个文件名会更复杂。基本上class user_frontend extends core_frontend 必须知道在哪里可以找到这两个类。两者都必须包括在内。

      如果你只想做new Frontend 你可以使用PHP5.3 的class_alias 将前端指向要使用的主类。低于 5.3。您可以使用 ServiceFinder,它知道如何将服务名称映射到类,然后使用 $service->get('frontend') 或使用 Dependency Injection framework 获取前端。

      编辑 我删除了之前给出的加载器代码,因为它正是遇到了这个问题。

      【讨论】:

        【解决方案5】:

        您可以有一个加载器类来决定要实例化哪个类:

        Loader::instance()->load('Frontend')
        

        【讨论】:

          猜你喜欢
          • 2013-03-04
          • 2011-01-16
          • 1970-01-01
          • 2011-06-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-20
          • 2019-03-31
          相关资源
          最近更新 更多