如果实用程序类是反模式,那么PHP中的替代方法是什么?

时间:2017-11-10 18:40:25

标签: php oop design-patterns anti-patterns utility-method

我正在尝试通过遵循最新的OOP设计模式来构建我自己的MVC框架(当然要更好地学习它)。我想知道,放置可重复代码的最佳实践是什么(用于保留在实用程序类中作为静态方法,这被认为不是一个好的模式)。

例如,我们想要使用点分隔的字符串遍历多维数组,我必须在几个类(它们是其他基类的子类)中使用此算法。如果不使用实用程序类并且不多次重复相同的代码,我该怎么做?

4 个答案:

答案 0 :(得分:2)

实用程序类没有任何问题,只是不要将所有不相关的实用程序功能整合到一个巨大的类中。通过它们的作用来区分(和命名空间)它们。例如,请参阅Zend FilterSymfony Filesystem

或者,如果需要此函数的类都具有公共父级,则可以将该函数放在最顶层或抽象中。

或者如果类没有共同的父级,您可以使用名为from scrapy_kafka.spiders import ListeningKafkaSpider from .. items import PageHtml from calendar import timegm import time class CrawlXxxxxxxUrlsSpider(ListeningKafkaSpider): name = 'crawl_xxxxxxx_urls_spider' allowed_domains = ["xxxxxxx.com"] topic = "xxxxxxx_search_page_urls" def parse(self, response): item = PageHtml() item['url'] = response.url item['html'] = response.body_as_unicode() item['ts'] = timegm(time.gmtime()) return item # .... or whatever 或类似的方法创建Trait。

答案 1 :(得分:1)

如果这些是实用程序函数,则在单独的命名空间中将它们定义为。类似于

的东西
<?php
namespace Utils;

function array_query($array, $query) {
   // code for traversing the array 
}

将它们放在一个或多个文件中,你会没事的。请记住将该文件包含在应用程序的boostrap阶段。

底线:停止滥用静态类,我们现在已经为那个sh * t设置了命名空间。

但是,并非所有你认为的&#34;效用函数&#34;实际上是。如果您开始使用OOP代码,某些代码应该放在关联的类中。例如&#34;电子邮件验证&#34;不应该进入&#34;效用函数&#34;但在课堂上:

class EmailAddress {

    private $emailAddress;

    public function __construct($emailAddress) {
        $this->assertValidEmailAddress($emailAddress);
        $this->emailAddress = $emailAddress;
    }

    private function assertValidEmailAddress($emailAddress) {
       if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
           throw new DomainException("Not an email address");
       }
    }

    public function __toString() {
        return $this->emailAddress;
    }
}

这些重复的域逻辑&#34;片段应该放在分离的实体中,然后您可以为其他类键入提示。然后你在某处使用它:

public function register(EmailAddress $email, SafePassword $password): User
{
   // your user registration logic
}

这样,您的各种服务可以执行活动,并使用try-catch来改进验证。

  

<强> P.S。
  您可能需要仔细研究您正在做的事情。那个虚线访问实用程序很整洁(我在10年前就像它一样),但实际上它是一个临时解决方案&#34;对于一个更深层次的问题:你不应该处理这么深的数组,你需要简化访问它们。

答案 2 :(得分:0)

  

实用程序类是反模式

真的不是。
在OOP中,使用实用程序类设计整个应用程序很可能是反模式,但定义实用程序类static方法提供例行/横向任务可能有意义。

不将实用程序方法与使用它们的现有类的方法混合,也可以提供实用程序类和使用者类的更好的内聚和可重用性。

当然作为替代方案,您可以使用实例方法定义类 这是有效的,更冗长,但具有提高类可测试性的优势。如果您需要模拟调用或切换到实用程序方法的其他实现,则必须优先考虑实例方法。

答案 3 :(得分:-1)

Laravel通过定义独立的&#34;帮助&#34;来做到这一点。功能。 CakePHP和Yii通过使用静态方法定义容器实用程序类(即&#34; Text&#34;或&#34; Xml&#34;)来完成它。编程语言做类似的事情(即PHP for line in file: if line.startswith('#'): print (line) line = line.rstrip('\n') field = line.split("\t") for item in field[2:3:1]: print(item) ,Java implode(),C&#39 {s} Math.round,Python strcpy等)。几乎所有东西都使用独立函数或静态类方法。

最终,最好的选择是主观。这取决于想要如何构建事物。研究PHP中的常见设计模式,并了解不同框架在实践中的感受。然后选择一种方法并保持一致。