函数数组的替代方法? [英] An alternative to an array of functions?

查看:108
本文介绍了函数数组的替代方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编程一个应用程序(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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆