是否存在静态调用对象方法的设计模式

时间:2015-04-03 09:55:27

标签: php algorithm design-patterns static

基本上我正在尝试创建一个用于处理文件和目录的库。

我们的想法是FileFindingFileReadingFileWriting等单独的课程。

我想要搜索的是有任何设计模式来实现类似:

只有一次课可以说

<?php namespace vendor/FileHandler;

 class FileHandler {}

现在在图书馆我有特定的课程,请说

<?php namespace vendor/FileHandler;

class FileFinder 
{
     /**
     * Find files by their types
     * 
     * @param string $path path to find files in.
     * @param mixed $type string or array of file type/types (extensions).
     * @return array array of file names.
     */
    public function findFilesByType($path, $type)
    {
        // do logic here.
        return $files;
    }
}

现在我希望我的图书馆用户使用主要课程FileFinder::findFilesByType()来调用FileHandler::findFilesByType();

请注意:FileFinder::findFilesByType()不是静态方法,但我希望将其用作class FileHanlder的静态方法

更新 我上面提到的问题与Laravel的Facade模式类似。但他们的实施超越了我的头脑。即使我不确定Facade模式是否会这样做。

2 个答案:

答案 0 :(得分:1)

您可以使用__callStatic

<?php

namespace vendor/FileHandler;

class FileHandler {

/**  PHP >= 5.3.0  */
public static function __callStatic($name, $arguments) {

  if($name == 'findFilesByType') {
    $obj = new FileFinder();
    return $obj->findFilesByType(implode(', ', $arguments));      
  }   
}
}
?>

呼叫:

FileHandler::FileHandler('/files', 'pdf');

更多信息:

  

http://php.net/manual/en/language.oop5.overloading.php#object.callstatic

答案 1 :(得分:1)

Facade应该保留每个类的静态实例,提供您自己想要转发给库用户的功能。

在Facade的静态方法中,利用上述对象并将方法调用转发给它们。 只有使用此方法,如果您转发的对象是无状态的, 否则你必须在facades方法中创建适当的对象,以便不在方法调用之间传播状态信息。

以下是java中的一个小例子,但是你得到了点

public class Facade {
    private static final HashComputer computer = new HashComputer();

    // since this operation changes state of accumulator,
    // it has to create one on each invocation
    public static List<String> accumulate(String... args) {
        Accumulator acc = new Accumulator();
        for (String arg : args)
            acc.add(arg);

        return acc.collect();
    }

    // this operation does not change state of the object it delegates to,
    // so there is no need to create a new instance on every invocation
    public static int computeHash(String s) {
        return computer.hashFor(s);
    }

    // has stateless instances
    private static class HashComputer {
        public int hashFor(String s) {
            return s.hashCode();
        }
    }

    // instances have state depending on state of list
    private static class Accumulator {
        List<String> arguments = new ArrayList<String>();
        public void add(String s) {
            arguments.add(s);
        }
        public List<String> collect() {
            return Collections.unmodifiableList(arguments);
        }
    }
}

严格地说,实现外观的这种确切方式恰好满足您的需求。 Facade不必是具有静态方法的实用程序类,它也可以是类的实例。

外观设计模式背后的原理是从一组类(或整个层)的内在函数中抽象出来,它们负责一些常见功能,封装操作并授予它们简单,可能是高级别的访问权限。


正如@PeeHaa在他的评论中提到的,这种静态门面方法确实不是OOP意义上的,因为违反了law of demeter,它说:

method的方法Class应该只调用方法

  • of Class
  • method 创建的对象的
  • 关于method
  • 的论点
  • 关于Class
  • 的实例变量

在这种意义上,你没有使用静态方法的外观,因为你在类上调用方法而不是实例上的方法。