如何在不修改太多代码的情况下专门化命名空间的 class 并使用它?
How can I specialize a class of a namespace and use it without modifying too much code?
我有一个基于名称空间的代码,有一个 "Model" 文件夹。我在我的代码中到处静态地调用我的模型:
\Myapp\Model\PersonModel::doSomething()
现在,我想在几个国家分发我的应用程序,并能够为某些国家覆盖 PersonModel 的某些功能(并为某些国家添加模型,等等)。
我会有:
\MyApp\Model\France\PersonModel::doSomething()
考虑到这一点,我希望能够使用专用版本:
- 没有修改太多代码
- 保留我的 IDE 代码完成
一个解决方案是为每个国家专门化每个控制器,并在所有地方使用完全限定的名称,但我不确定它是否现实(耗时,甚至可能无法正常工作)。
另一种解决方案是覆盖每个模型,并在某个地方添加一个函数,该函数会给我完全限定的名称 class(对于当前国家/地区),但代码会变得丑陋,我会丢失代码补全。
第三种解决方案是为每个国家建立一个存储库,并尝试修改所有内容,以便核心代码位于 Git 子模块中,其他所有内容都是专门的 classes.. . 这对我来说似乎是最好的解决方案,但它似乎是 Titan 的作品,我更希望所有国家都在同一个存储库中以控制事情。
我真的没有别的想法。我敢肯定我不是唯一遇到该问题的人,但我进行了搜索但一无所获。请告诉我命名空间有一个我不知道的神奇功能,或者什么? :)
编辑:部分解决
我现在使用的是自定义自动加载器,它将加载特定国家/地区的正确内容class。但是所有国家/地区特定的 classes 将共享 same 名称空间(这将起作用,因为我们在给定时间仅使用 1 个国家/地区)。然而,我失去了代码完成,但这是一个我可以接受的权衡。如果有人有也允许保持代码完成的解决方案,请随时回答!
好的,我找到了一个全球满意的解决方案:
所有特定国家的 类 将共享 相同的 名称空间(例如 "Myapp\Model\Custom*"),这不会导致冲突,因为只有 1 个国家/地区一次。
自定义自动加载器将根据当前国家/地区加载正确的 class/file。
此解决方案的不便之处在于:
- 不可能同时"use"多个国家(这不是目标,所以没关系)
- 丢失代码补全:(
优点是:
- 比为每个国家/地区创建存储库更省时更费力
- 全局清理代码和代码结构
请随时post更优雅的解决方案,我将很高兴阅读(并接受)!
另一个想法,来自我在评论中的想法。移动这个:
\Myapp\Model\PersonModel
到这里(随机位置,因为我不知道你的默认区域):
\Myapp\Model\Germany\PersonModel
您现在将有两个 class 名称空间中有一个国家/地区,当然您可以添加更多。您现在可以添加一个新的广义 class,因此:
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
(see here) will ensure you retain auto-completion, and you can learn more about the call magic methods here.
当然,请确保您的特定语言 classes 引用父 class,这样您就不会复制大块代码。有些方法也可能不关心语言,在这种情况下,它们可以进入 \Myapp\Model\PersonModel
,好处是它们不需要手动 phpdoc 条目。
我有一个基于名称空间的代码,有一个 "Model" 文件夹。我在我的代码中到处静态地调用我的模型:
\Myapp\Model\PersonModel::doSomething()
现在,我想在几个国家分发我的应用程序,并能够为某些国家覆盖 PersonModel 的某些功能(并为某些国家添加模型,等等)。
我会有:
\MyApp\Model\France\PersonModel::doSomething()
考虑到这一点,我希望能够使用专用版本:
- 没有修改太多代码
- 保留我的 IDE 代码完成
一个解决方案是为每个国家专门化每个控制器,并在所有地方使用完全限定的名称,但我不确定它是否现实(耗时,甚至可能无法正常工作)。
另一种解决方案是覆盖每个模型,并在某个地方添加一个函数,该函数会给我完全限定的名称 class(对于当前国家/地区),但代码会变得丑陋,我会丢失代码补全。
第三种解决方案是为每个国家建立一个存储库,并尝试修改所有内容,以便核心代码位于 Git 子模块中,其他所有内容都是专门的 classes.. . 这对我来说似乎是最好的解决方案,但它似乎是 Titan 的作品,我更希望所有国家都在同一个存储库中以控制事情。
我真的没有别的想法。我敢肯定我不是唯一遇到该问题的人,但我进行了搜索但一无所获。请告诉我命名空间有一个我不知道的神奇功能,或者什么? :)
编辑:部分解决
我现在使用的是自定义自动加载器,它将加载特定国家/地区的正确内容class。但是所有国家/地区特定的 classes 将共享 same 名称空间(这将起作用,因为我们在给定时间仅使用 1 个国家/地区)。然而,我失去了代码完成,但这是一个我可以接受的权衡。如果有人有也允许保持代码完成的解决方案,请随时回答!
好的,我找到了一个全球满意的解决方案:
所有特定国家的 类 将共享 相同的 名称空间(例如 "Myapp\Model\Custom*"),这不会导致冲突,因为只有 1 个国家/地区一次。
自定义自动加载器将根据当前国家/地区加载正确的 class/file。
此解决方案的不便之处在于:
- 不可能同时"use"多个国家(这不是目标,所以没关系)
- 丢失代码补全:(
优点是:
- 比为每个国家/地区创建存储库更省时更费力
- 全局清理代码和代码结构
请随时post更优雅的解决方案,我将很高兴阅读(并接受)!
另一个想法,来自我在评论中的想法。移动这个:
\Myapp\Model\PersonModel
到这里(随机位置,因为我不知道你的默认区域):
\Myapp\Model\Germany\PersonModel
您现在将有两个 class 名称空间中有一个国家/地区,当然您可以添加更多。您现在可以添加一个新的广义 class,因此:
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
(see here) will ensure you retain auto-completion, and you can learn more about the call magic methods here.
当然,请确保您的特定语言 classes 引用父 class,这样您就不会复制大块代码。有些方法也可能不关心语言,在这种情况下,它们可以进入 \Myapp\Model\PersonModel
,好处是它们不需要手动 phpdoc 条目。