函数数组的替代方法? [英] An alternative to an array of functions?
问题描述
我正在编程一个应用程序(php),该应用程序需要很长的相似但不同的功能列表,这些功能由一组键调用:
I'm programming an app (php) which requires a very long list of similar yet different functions, which are being called by a set of keys:
$functions = [
"do this" => function() {
// does this
},
"do that" => function() {
// does that
}
]
etc.
我选择将相似的函数放置在数组中,因为它们不相似足够-使用充满条件语句的一个大函数获得相同的结果不是会工作。而且我确实只能通过按键来调用它们,例如:
I've chosen to place the similar functions in an array because they are not similar enough - getting the same result with one big function which is full of conditional statements isn't gonna work. And I do need to be able to call them only by key, for example:
$program = ["do this", "do that", "do this"];
foreach ($program as $k => $v) {
$functions[$v]();
}
这种功能数组结构引起很多问题,例如我m很难从另一个数组函数中调用一个数组函数,例如这不起作用:
Thing is this functions-array structure is causing many problems, for example I'm having a hard time calling one array function from within another array function, e.g. this doesn't work:
"do that" => function() {
$functions["do this"]();
}
也不要这样:
"do that" => function() {
global $functions;
$functions["do this"]();
}
或此:
"do that" => function($functions) {
$functions["do this"]();
}
$functions["do that"]($functions);
我想我可以用一个很长的 switch语句来实现一个巨大的功能:
I guess I could have one giant function with a long switch statement:
function similar_functions($key) {
switch ($key) {
case "do this":
// does this
break;
case "do that":
// does that
break;
}
}
但这似乎并不是一个好习惯。也许是?
But that doens't really seem like good practice. Or maybe it is?
那么,我有什么选择?我应该采用开关结构吗?还是有另一个更好的解决方案?
So, what are my alternatives? Should I go with the switch structure? Or is there another, better solution?
推荐答案
关闭对于PHP的性能和内存使用而言是昂贵的。程序编码激起了一大堆泥巴,意大利面条式编码和其他反模式。开关结构很难测试,并且违反了 OCP 。
Closures are expensive for performance and memoryusage in php. Procedural coding provoked a big ball of mud, spaghetti code and other anti patterns. Switch structures are very hard to test and it's a violation of OCP.
您应该更喜欢 SOLID 中的OOP,以避免冗余,提高可伸缩性和可维护性。这是提供一组可重复使用的功能的最佳实践。
您还可以将代码分成不同的层和模块,以降低复杂性并提高互换性。
You should prefer OOP in SOLID way to avoid redundancy, improving scalability and maintainablity. That is the best practice to provide a set of functions which are reuseable. You can also seperate your code in layers and modules to reduce complexity and improve interchangability.
在您的情况下,您的类可以实现__invoke 称为可调用的,并且您的密钥可以是这些类的完全限定名称空间,因此您可以称之为函数。
从现在开始,您还可以使用继承,多态性或复合,装饰器等设计模式来重用其他功能或添加功能。
In your case your classes can implement __invoke to call it as invokable and your keys could be the fullqualified namespaces for these classes, so you can call it like a function. From now on you can also use inheritence, polymorphism or design patterns like composite, decorator etc. to reuse other functions or to add functions.
这是一个简单的示例。
<?php
use Foo\Bar;
class This
{
public function __invoke()
{
$this->execute();
}
public function execute()
{
/* ... */
}
}
class That extends This
{
public function execute()
{
/* ... */
}
}
$namespaces = array("\Foo\Bar\This", "\Foo\Bar\That");
foreach ($namespaces as $fullQualifiedNamespace) {
/** @var callable $fullQualifiedNamespace */
$fullQualifiedNamespace();
}
通过为This and That实现特定的接口也可以实现此行为。
在迭代中,您可以检查界面以调用已定义的合同。或者,您可以构建一个流程类,在其中可以添加实现此接口的对象。 Process类可以执行所有附加的对象(责任链)。
This behavior is also reachable by implementing a specific interface to This and That. Within iteration you can check the interface to call the defined contract. Or you build a Process Class where you can add objects which implements this interface. The Process class can execute all attached objects (Chain of Responsibility).
我更喜欢大多数开发人员可以理解的责任链模式,而不是像PHP的__invoke拦截器这样的 magic 。在工厂中,您可以定义链,也可以定义对链或附加链对象的其他依赖关系。
I would prefer the Chain of Responsibility Pattern this is understandable by most developers and not so magic like PHP's __invoke interceptor. In a factory you can define your chain and you are able to define other dependencies to the chain or to the attached chain objects.
这篇关于函数数组的替代方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!