2

注意随意提出一个更好的标题,因为我认为“生成代码”和“抽象”可能不是我想问的最佳表达方式:)

我正在寻找一种从某种抽象层生成 PHP 代码的良好模式/标准方法。

例子

我已经构建了一组充当文本处理过滤器的类。这些过滤器可以链接在一起以将一些输入文本转换为一些其他输出文本,例如

Input "Hello 'CRUEL' World" 
>> RegexFilter('(.*?)') [extract everything between '']
>> ToLowerFilter [lowercase the extracted text]
Output: cruel

结果代码

相应的源代码如下所示:

$input = "Hello 'CRUEL' world";
$pattern = "#(.*?)#";
$first = new RegexFilter($pattern);
$second = new ToLowerFilter();
$first->setNextFilter($second);
$ouput = $first->Transform($input);
echo $output; // cruel

我想创建某种抽象层,以便最终用户(非程序员)可以构建自己的过滤器链,而无需自己编写代码。“抽象”是指像 XML、JSON、存储在数据库等中的东西。

XML 示例(建议)

<filters>
 <filter name='Regex'>
  <properties>
   <property name='pattern'>'(.*)'</property>
  </properties>
  <nextfilter name='ToLower'>
   <properties/>
  </filter>
 </filter>
</filters> 

备注:示例非常简单。想想更高级的东西,比如“复杂对象作为过滤器的属性”、“过滤器的继承”(上面的过滤器可以得到名称“RegexToLowerFilter”并且可以被其他过滤器引用)等等。

方法/想法

是否有解决此类问题的标准方法?到目前为止,我已经考虑为每个过滤器构建自定义 XML、JSON 等序列化器/反序列化器,但这似乎需要做很多工作并且可能容易出错,因为它是为每个过滤器单独完成的。此外,我想这需要使每个可能的依赖项也以相同的方式可序列化——这在使用第三方库(例如JsonPath)时可能会出现问题。

我想最优雅的方法是创建Domain Specific Language。不幸的是,构建编译器并不是最简单的任务,而且可能并不总是适合该领域的每个问题。(话又说回来,请随时纠正我:))

TL;博士

我正在寻找一种合适的方式/模式来在(非程序员)最终用户和我的源代码之间建立一个抽象层。解决方案应该采取“简化”的抽象并“生成”相应的代码。

4

1 回答 1

2

您正在尝试做的事情称为“模型驱动开发”

查看 Eclipse 模型到文本 (M2T) 项目中的各种开源子项目。我最喜欢的是 JET,但还有其他具有不同规范和运行时特性的。

尽管事实上我非常喜欢使用模型驱动开发来解决这类问题,但我想提醒您使用这些技术(或您自己的实现)来解决这个特定问题。如果您的目标受众真的是一群非程序员,那么他们在学习您的 DSL(语法和关键字)时会遇到与您试图隐藏的原始语言一样的麻烦。如果有原始语言的开发工具(调试器、编辑器等),则比较(DSL 与原始语言)会变得更糟。模型驱动技术在应用于需要自动化工作的更多专家开发人员时往往比应用于寻求奇迹的不专业开发人员时更成功。

于 2014-08-26T14:35:27.503 回答