介绍
模板方法一般是复用一些程序流程,来达到减少代码量,提高系统逻辑清晰性和提高维护效率的目的。如在我们需要采集一些新闻网站的数据,一般就是开发对应网站的爬虫来采集数据,爬虫开发从整体上分为下载网页-解析网页-数据入库流程。但是下载网页和数据入库流程应该都是一样的流程,所以可以提取到公共的类,然后定义解析网页是抽象方法,不同的网站爬虫实现不同的解析。
结构
- 定义一个抽象类
- 定义一个流程结构
- 具体的实现方法定义为抽象方法
- 实现各自的的抽象方法的逻辑
类图结构
实现
定义一个爬虫抽象类
类有一个起始url, 通过构造函数来赋值
然后定义三个采集流程downloadPage,parsePage,pipeline
在run方法中把流程串起来,同时下载网页和入库都是一样 的,所以在该类中实现,解析流程留给具体的爬虫来实现。
public abstract class Spider {
private String url;
public Spider(String url) {
this.url = url;
}
protected Object downloadPage() {
System.out.println("下载网页" + url);
return new Object();
}
abstract Object parsePage(Object page);
protected void pipeline(Object result) {
System.out.println("数据入库到爬虫库中");
}
public void run() {
//第一步, 下载网页数据
Object page = downloadPage();
//第二步, 解析网页数据
Object result = parsePage(page);
//第三步, 数据入库
pipeline(result);
}
}
定义新浪新闻的爬虫类
public class SinaNewsSpider extends Spider{
public SinaNewsSpider(String url) {
super(url);
}
@Override
Object parsePage(Object page) {
System.out.println("解析新浪网站新闻");
return new Object();
}
}
定义腾讯新闻的爬虫类
public class TencetNewsSpider extends Spider{
public TencetNewsSpider(String url) {
super(url);
}
@Override
Object parsePage(Object page) {
System.out.println("解析腾讯新闻");
return new Object();
}
}
定义具体的场景类,启动相关爬虫
public class Client {
public static void main(String[] args) {
new SinaNewsSpider("sina url").run();
System.out.println();
new TencetNewsSpider("tencent url").run();
}
}
打印输出
下载网页sina url
解析新浪网站新闻
数据入库到爬虫库中
下载网页tencent url
解析腾讯新闻
数据入库到爬虫库中
优缺点
使用模板方法的模式,使得流程一致的业务逻辑复用起来,系统结构清晰,同时也减少了开发代码量和提高维护效率,但是一旦改动可能会对下属子类都有影响,扩展器起来不方便。