Jsoup中的设计模式⼀
1、组合模式
Jsoup中⼀个显⽽易见的模式是组合模式(定义:将对象组合成树形结构以表⽰部分整体的关系,Composite使得⽤户对单个对象和组合对象的使⽤具有⼀致性。)
Node类的定义正好是符合“树”的定义,如图
看⼀下它的⼦类
其中最重要的是Element,表⽰⼀个html元素
Document继承Element,表⽰整个⽂档
PS.Token(符号类)和Evaluator(识别器类)咋⼀看也像是组合模式,当是不符合组织成树形这⼀条。
2、外观模式
TreeBuilder(树构造器类)就是⼀个
包含字符输⼊流、符号分析器、当前符号、已打开元素栈、语法解析错误列表、⽬标⽂档等。提供⼀个⽐较简洁的parse接⼝给上层。
Document parse(String input, String baseUri, ParseErrorList errors) {
initialiseParse(input, baseUri, errors);
runParser();
return doc;
}
Parser(解析器类)进⼀步简化了接⼝TreeBuilder的接⼝(也是因为TreeBuilder不⽌⼀种实现)
提供更为简化的静态的parse接⼝
public static Document parse(String html, String baseUri) {
TreeBuilder treeBuilder = new HtmlTreeBuilder();
return treeBuilder.parse(html, baseUri, Tracking());
}
最后Jsoup(Jsoup的⼊⼝类)再⼀次封装了parse⽅法,作为框架的终极“门⾯”,提供给了开发者。
Jsoup提供了parse和它的各种快捷调⽤⽅式
当然作为最⾼级门⾯类,Jsoup还封装了过滤标签和发起http连接等API
3、状态模式
TokeniserState(记录符号解析器的状态)
HtmlTreeBuilderState(记录html树构造器的状态)
4、解释器模式
QueryParser(css查询选择表达式解析器),Jsoup⽀持像jQuery⼀样⽤css选择器表达式查询dom元素,就是靠这个类实现了解析。
具体解析算法实现nodeselector
/**
* Parse the query
* @return Evaluator
*/
Evaluator parse() {
if (tq.matchesAny(combinators)) { // if starts with a combinator, use root as elements
evals.add(new StructuralEvaluator.Root());
sume());
} else {
findElements();
}
while (!tq.isEmpty()) {
// hierarchy and extras
boolean seenWhite = tq.consumeWhitespace();
if (tq.matchesAny(combinators)) {
sume());
} else if (seenWhite) {
combinator(' ');
} else { // E.class, E#id, E[attr] etc. AND
findElements(); // take next el, #. etc off queue
}
}
if (evals.size() == 1)
(0);
return new CombiningEvaluator.And(evals);
}
1)将查询表达式串,构造为符号队列(TokenQueue)
2)⼀⼀消费掉符号队列⾥的符号,最后构造为⼀个识别器对象(Evaluator)
3)在selector中从页⾯根元素起遍历所有节点,匹配符合识别器的所有元素数组。
5、模板⽅法模式
Template Method ,定义⼀个操作中的算法的⾻架,⽽将⼀些步骤延迟到⼦类中,Template Method使得⼦类可以不改变⼀个算法的结构即可以重定义该算法得某些特定步骤。
例⼦,TreeBuilder和它的⼦类
处理⼀个符号的步骤取决于是HTML还是XML,所有延迟到⼦类实现
protected abstract boolean process(Token token);
XmlTreeBuilder重写了⽗类的初始化⽅法
public class XmlTreeBuilder extends TreeBuilder {
@Override
protected void initialiseParse(String input, String baseUri, ParseErrorList errors) {
super.initialiseParse(input, baseUri, errors);
stack.add(doc); // place the document onto the stack. differs from HtmlTreeBuilder (not on stack)
doc.outputSettings().syntax(Document.l);
}
....
HtmlTreeBuilder重新了⽗类的解析⽅法

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。