【问题标题】:Which is the correct design pattern for my PHP application?我的 PHP 应用程序的正确设计模式是什么?
【发布时间】:2012-07-20 17:23:00
【问题描述】:

我一直在努力寻找实现我的系统的好方法,该系统基本上与字符串中的节目的季节和剧集编号相匹配,您可以在此处查看当前工作代码:https://github.com/huddy/tvfilename

我目前正在重写这个库,并希望有一种更好的方式来实现匹配的发生方式,目前基本上它的工作方式是:

有一个包含类的文件夹(称为处理程序),每个处理程序都是一个实现接口以确保调用 match() 方法的类;如果存在,则此匹配方法使用存储在该处理程序类(其中有很多)的属性中的正则表达式来尝试匹配季节和剧集。

该类通过将每个处理程序实例化到存储在属性中的数组来加载所有这些处理程序,当我想尝试匹配一些字符串时,该方法会遍历这些对象调用 match();然后返回第一个返回 true 的结果集,其中包含与之匹配的季节和剧集。

我真的不喜欢这种方式,这对我来说有点 hacky,我希望设计模式可以提供帮助,我的最终目标是使用最佳实践来做到这一点,我想知道我应该使用哪一个利用?

存在的其他问题是:

  • 多个处理程序可以匹配一个字符串,因此它们必须防止更贪婪的处理程序首先匹配,不确定这是否可以解决,因为某些正则表达式模式必须是贪婪的,但是可能是一个评分系统,它显示了匹配正确率的百分比,但我不知道如何实际实现这一点。

  • 如果实例化所有这些处理程序是一种好方法,我认为速度很重要,但使用最佳实践和坚持设计模式来创建良好、可扩展和可维护的代码是我的最终优先事项。值得注意的是,处理程序类有时会做其他事情,而不仅仅是正则表达式匹配,它们有时会通过删除常用词等来准备要匹配的字符串。

为任何帮助干杯 比利

【问题讨论】:

  • 您可以结帐Horde Routes
  • 你想多了。您的贪心问题可以通过将数组从最不贪婪排序到最贪婪来轻松解决,并且您的正则表达式都可以在一个类中。我没有看到比这更直接或更干净的方法了。

标签: php regex oop design-patterns


【解决方案1】:

为每个正则表达式创建一个类是非常低效的,你在这里混淆了类和数据。您可以将所有正则表达式存储在配置数组或单独的类或 XML 文件中 - 没关系。然后一个方法可以接受所有正则表达式,遍历它们并执行匹配。 如果季节并不总是匹配[1],您可以使用命名子模式 - 这将解决该问题。

至于您的模式顺序问题,您可以简单地将所有模式按您喜欢的顺序排列 - 从最具体的模式到更一般的模式。

【讨论】:

    【解决方案2】:

    您可以将此pattern to implement complex case analysis 改编为PHP。这或多或少是你一直在做的事情。您定义所有案例,实现一个条件,说明案例何时适用,以及当您在该案例中时如何解决问题。该模式将允许您决定在多个案例适用时该怎么做(选择一个,优先考虑另一个,或任何您想要的)。

    如果您将格式命名为 S01E01 之类的更好听的名称,我也是个好主意

    SddEdd
    SnnEnn
    SDigitDigitEDigitDigit
    STwoDigitsETWoDigits
    

    而不是格式1,格式2。 您还可以稍微修改模式以将对象实例用于案例的条件和解决方案,因此您将能够使用单个类处理所有 RegExps 案例 new RegexpCase("S(?:\d{2})E(?:\d{2})"); 以及所有其他不只是带有类的正则表达式来解决该案例的案例。

    【讨论】:

      【解决方案3】:

      我认为您需要根据您想要的参数为您的模式顺序设置一个偏好顺序。 我认为第二个答案确实很好地回答了您的问题。而且您的代码似乎做得很好。看起来写得很好

      【讨论】:

        【解决方案4】:

        我个人更喜欢在这种情况下使用单独的类,如果您采用这种方法(即如果您确实需要操作字符串),您的代码库将更加灵活。如果您看一下 Zend 如何实现 Zend_Validate 和 Zend_Filter ,它们与当前实现有一个非常相似的方法(循环在类上运行 ->validate() 和 ->filter() 的属性)。

        我会有一个类似这样的结构:

        • App_Tv_Match
        • App_Tv_Match_Abstract
        • App_Tv_Match_Collection
        • App_Tv_Match_SXXEXX
        • App_Tv_Match_SeasonXEpisodeX

        (不过,你的命名可能会让课程感到厌烦)。

        但在摘要中,我会有一个类似的设置:

        Abstract Class App_Tv_Match_Abstract
        {
             protected $_returnOnMatch = false;
             protected $_priority      = 1;
        }
        

        我的 App_Tv_Match_Collection 类将注入匹配类 - 然后集合类将使用匹配类处理排序和匹配。如果 Match 类将“returnOnMatch”标记为 true,那么如果匹配,我将停止尝试并返回这个(即对于非贪婪的),但是如果没有匹配的 returnOnMatch 类,那么我将返回具有最高优先级的那个(或者使用排序,或集合类中的简单循环)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-25
          • 2020-11-08
          • 1970-01-01
          • 1970-01-01
          • 2022-08-20
          • 1970-01-01
          相关资源
          最近更新 更多