Aur*_*mas 6 php oop factory-pattern
我经常做PHP项目,旨在从网页中删除分层数据并将它们保存到数据库中(基本上,构建数据 - 考虑抓住拥有数据的政府网站,但不以结构化方式提供).每一次,我都试图提出一个允许我实现以下目标的OOP设计:
到目前为止,我还没有找到解决方案,但最接近我得到的是这样的:
我为数据容器定义了一个抽象类,它将实现常见的树遍历函数:
abstract class DataContainer {
protected $parent = NULL;
protected $children = NULL;
public function getParent() {
return $this->parent;
}
public function getChildren() {
return $this->children;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我有实际的数据容器.想象一下,我正在将参与议会会议的数据下载到"坐在一起的具体问题"中.我会SessionContainer,SittingContainer,QuestionContainer将所有的扩展DataContainer.
每个会话,就座和问题数据都从不同的URL中删除.留下将URL内容放在一边的机制,我只想说我需要刮刀类,它将采用容器和DOmDocument进行实际解析.所以我会定义一个这样的通用接口:
interface Scraper {
public function scrapeData(DOMDocument $Dom, DataContainer $DataContainer);
}
Run Code Online (Sandbox Code Playgroud)
然后,每个会话,坐着和问题都有自己的刮刀,它们实现了界面.但我也想确保他们只能接受他们想要的容器.所以它看起来像:
class SessionScraper implements Scraper {
public function scrapeData(DOMDocument $DOM, SessionContainer $DataContainer) {
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我将有一个通用Factory类,它也实现了Scraper接口,只是将刮擦分配给相关的scraper.像这样:
public function scrapeData(DOMDocument $DOM, DataContainer $DataContainer) {
//get the scraper from configuration array
$class = $this->config[get_class($DataContainer)];
$craper = new $class();
$class->scrapeData($DOM, $DataContainer);
}
Run Code Online (Sandbox Code Playgroud)
这是将在代码中实际调用的类.非常类似,我可以处理保存到DB - 每个数据容器都可以有DBSaver类,它将实现DBSaver接口.同样,所有调用都可以通过Factory类完成,这也将实现DBSaver接口.
一切都很完美,但问题是实现接口的类应该实现接口的精确签名.例如,方法SessionScraper::scrapeData不能只 接受SessionContainer对象,它必须接受所有DataContainer对象.但它并不意味着!
最后,问题是:
instanceof和类似检查中强制执行类型,而不是通过类型提示强制执行?提前感谢所有的建议/批评.如果有必要的话,我很高兴有人推翻这个代码!
Container涌入眼帘。这个名称非常通用,您可能需要更动态的名称。我想你已经拥有Data了classify,所以它有一个type。
因此,您应该将确切的接口硬编码到类型提示中,而应该动态地解决这个问题。
如果现在每个Container都有一个type,则Scraper可以发出信号/告知它是否适用type于Container。
抓取的具体形式实际上就是你对特定数据进行解析所采用的策略。您的容器封装了此策略,提供标准化数据的接口。
您只需要在Container和之间添加一些逻辑/契约Scraper,以便它们可以相互交谈。您可以将该合同放入两者的界面中。
如果你想扩展它,这也将允许你拥有一个Scraper可以处理多个的东西。types
对于您的Container,请查看 SPL 以及实现一些接口,以便您拥有可用的迭代器(和递归迭代器)。这可能是您所指的通用结构,并且 SPL 可以提高您的可用性Container。
您不需要在 OOP 中对所有内容进行硬编码,您可以保持动态,尤其是在 PHP 中,您通常在运行时解决问题。
这也将使您能够更轻松地更换Scrapers新版本。由于
Scrapers现在根据定义有一个类型(如上所述),您可以在运行时解析哪个具体类应该执行抓取,例如从一个漂亮的文件系统结构中的 .php 文件动态加载它们。
只是我的2分钱。
| 归档时间: |
|
| 查看次数: |
583 次 |
| 最近记录: |