基本上我正在尝试创建一个用于处理文件和目录的库。
我们的想法是FileFinding
,FileReading
,FileWriting
等单独的课程。
我想要搜索的是有任何设计模式来实现类似:
只有一次课可以说
<?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模式是否会这样做。
答案 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
应该只调用方法
Class
method
创建的对象的method
Class
在这种意义上,你没有使用静态方法的外观,因为你在类上调用方法而不是实例上的方法。