Webページから階層データを掻き集めてDBに保存するように設計されたPHPプロジェクトをよくします(基本的にはデータを構造化しますデータは構造化された方法で提供しません)。たびに、私は私が次のことを達成できるようになるOOPのデザインを思い付くしよう:PHP OOPデザイン - ジェネリックインターフェイスを実装しながら特定の子クラスにパラメータを限定する
- オリジナルのウェブページはの簡単な拡張を許可する
- を変更する場合には簡単に、新しいものにスクリプトを解析現在のHTMLを置き換えますこれらのプロジェクトは他の人が取ってビルドするためのものであるため、データは削り取られて保存されます。私の目的は「基本」データを収集することですが、他の人は余分なものを含めることを決めるかもしれませんが、保存方法などを変更することがあります。
これまでのところ、このようなことは何か:
が、私は一般的なツリートラバース機能を実装し、データコンテナのための抽象クラスを定義します。abstract class DataContainer {
protected $parent = NULL;
protected $children = NULL;
public function getParent() {
return $this->parent;
}
public function getChildren() {
return $this->children;
}
}
そして私は、実際のデータコンテナを持っています。想像してみると、私は、議会のセッションへの参加に関するデータを「座っている特定の質問」レベルまで掘り下げています。私はSessionContainer
、SittingContainer
、QuestionContainer
を持っていて、それらはすべてDataContainer
になります。
各セッション、座っているデータおよび質問データは、別のURLからスクレイプされています。 URLコンテンツを取り除くメカニズムを残して、実際に解析するためにコンテナとDOmDocumentを取るスクレイパークラスが必要だとしましょう。 、そして、セッションのそれぞれを
interface Scraper {
public function scrapeData(DOMDocument $Dom, DataContainer $DataContainer);
}
座っての質問は、インターフェイスを実装し、独自のスクレーパーを持っているでしょう。だから私は、このような一般的なインタフェースを定義します。しかし、私は彼らが意味するコンテナだけを受け入れることもできるようにしたいと思います。だから、それは次のようになります。
class SessionScraper implements Scraper {
public function scrapeData(DOMDocument $DOM, SessionContainer $DataContainer) {
}
}
最後に、私はまた、スクレーパーインタフェースを実装し、ちょうど関連のスクレーパーにスクレイピングを配布し、一般的なFactory
クラスを持っているでしょう。このように:
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);
}
これは実際にコードで呼び出されるクラスです。同様に、DBに保存することもできます。各データコンテナはDBSaverインターフェイスを実装するDBSaverクラスを持つことができます。ここでも、すべての呼び出しはFactory
クラスを介して実行できます。これはDBSaverインターフェイスも実装します。
すべてが完璧ですが、問題はインターフェイスを実装するクラスがインターフェイスの正確な署名を実装する必要があることです。例えば。メソッドSessionScraper::scrapeData
はのみ受け入れることができませんSessionContainer
オブジェクトはすべてDataContainer
オブジェクトを受け入れる必要があります。しかしそれは意味がありません!最後に
、質問:
- は私の設計が間違っていると私は完全に別の方法ですべてを構築すべきですか? (どうやって?)、または:
- 私のデザインはOKです。タイプヒントではなく、
instanceof
と同様のチェックを使ってメソッド内で型を強制する必要がありますか?
すべての提案/批評に感謝します。私は、必要に応じて、このコードを頭の中で覆す人に完全に満足しています!
広範な回答をいただきありがとうございます - 他にもいくつかのアイデアを引き起こしました。 1つの説明 - すべてのデータを保持するための1つのデータ/コンテナクラスを持ち、子クラスを作成するのではなくタイププロパティで識別することを基本的にお勧めしていることを正しく理解していますか?または、両方のタイプのプロパティと子クラスになりますが、スクレイパーは型だけを考慮に入れますか? – Aurimas
あなたのデータは特に分かりませんので、わかりにくいです。データが非常に共通する場合は、プロパティが異なるだけで、多くのデータクラスを作成する必要はなく、動的プロパティを使用することもできます。後で全体的なアプリケーションの方がはるかに優れています。ほとんどの場合、スクレーパーは変更され、時にはデータが変更されます。いくつかのウェブサイトが少し変更されただけなので、常に新しいデータクラスを作成する必要があります。良くない :) – hakre