如何在不修改太多代码的情况下专门化命名空间的类并使用它


How can I specialize a class of a namespace and use it without modifying too much code?

我有一个基于命名空间的代码,有一个"模型"文件夹。我在代码中的任何地方静态调用我的模型:

'Myapp'Model'PersonModel::doSomething()

现在,我想在多个国家/地区分发我的应用程序,并能够覆盖某些国家/地区 PersonModel 的某些功能(并为某些国家/地区添加模型,依此类推)。

我将有:

'MyApp'Model'France'PersonModel::doSomething()

我希望能够使用专用版本,并考虑到这一点:

  • 不要修改太多代码
  • 保持我的 IDE 代码完成

一种解决方案是为每个国家/地区专门化每个控制器,并在任何地方使用完全限定的名称,但我不确定这是否现实(耗时,甚至可能不起作用)。

另一种解决方案是覆盖每个模型,并在某处添加一个函数,该函数将为我提供完全限定类的名称(针对当前国家/地区),但代码会变得丑陋,并且我将失去代码完成。

第三种解决方案是为每个国家/地区建立一个存储库,并尝试修改所有内容,以便核心代码位于 Git 子模块中,其他所有内容都是专门的类......这对我来说似乎是最好的解决方案,但它似乎是泰坦的作品,我宁愿将所有国家都放在同一个存储库中以控制事情。

我真的没有其他想法。我敢肯定我不是唯一一个有这个问题的人,但我搜索了一下,什么也没找到。请告诉我,有一个我不知道的命名空间的神奇功能,或者其他什么?:)


编辑:这已部分解决

我现在正在使用自定义自动加载器,它将加载正确的特定于国家/地区的类。但是所有特定于国家/地区的类将共享相同的命名空间(这将起作用,因为我们在给定时间仅使用 1 个国家/地区)。但是,我丢失了代码完成,但这是我可以接受的权衡。如果有人有一个解决方案,也可以保持代码完成,请随时回答!

好的,

我找到了一个全球满意的解决方案:

所有特定于国家/地区的类将共享相同的命名空间(例如"Myapp''Model''Custom*"),这不会引起冲突,因为一次只有 1 个国家/地区。

自定义自动加载器将根据当前国家/地区加载正确的类/文件。

此解决方案的缺点是:

  • 不可能同时"使用"多个国家(这不是目标,所以没关系)
  • 丢失代码完成:(

优点是:

  • 比为每个国家/地区创建存储库要省时得多,耗时和耗时
  • 全局干净的代码和代码结构

请随时发布一个更优雅的解决方案,我很乐意阅读它(并接受它)!

另一个

想法,遵循我在评论中的想法。移动这个:

'Myapp'Model'PersonModel

到这里(随机位置,因为我不知道您的默认领土):

'Myapp'Model'Germany'PersonModel

现在,命名空间中将有两个带有国家/地区的类,当然还可以添加更多类。您现在可以添加新的通用类,因此:

namespace 'Myapp'Model;
/*
 * Document your methods here using @method, so you get autocompletion
 */
class PersonModel
{
    public function __callStatic($name, $args)
    {
        // Convert the call to an appropriate static call on the correct class.
        // The first parameter is always the country name, which you can examine
        // and then remove from the list. Throw an exception if $args[0] is
        // empty.
    }
}

然后,您可以执行以下操作:

'MyApp'Model'PersonModel::doSomething('France', $args);

使用 @method(请参阅此处)将确保您保留自动完成功能,您可以在此处了解有关调用魔术方法的更多信息。

当然,请确保您特定于语言的类引用父类,这样您就不会复制大型代码。有些方法也可能不关心语言,在这种情况下,它们可以进入 'Myapp'Model'PersonModel ,好处是它们不需要手动 phpdoc 条目。