设计模式课程 设计模式精讲 21-3 观察者模式源码解析

1    源码解析

1.1    源码解析1(jdk中的应用)

1.2    源码解析2(Spring中的应用)

1.3    源码解析为何算出666?

 

1    源码解析
1.1    源码解析1(jdk中的应用

java.util.regex.Pattern

(java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现)

1.2    源码解析2(Spring中的应用)

测试类:(通过el表达式计算出结果)(以下代码中红色粗体为跳转顺序)

package com.geely.design.pattern.behavioral.interpreter;

import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;

/**
 * Created by geely
 */
public class SpringTest {
    public static void main(String[] args) {
        org.springframework.expression.ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression("100 * 2 + 400 * 1 + 66");
        int result = (Integer) expression.getValue();
        System.out.println(result);

    }
}

应用类1:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.expression.common;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;

public abstract class TemplateAwareExpressionParser implements ExpressionParser {
    private static final ParserContext NON_TEMPLATE_PARSER_CONTEXT = new ParserContext() {
        public String getExpressionPrefix() {
            return null;
        }

        public String getExpressionSuffix() {
            return null;
        }

        public boolean isTemplate() {
            return false;
        }
    };

    public TemplateAwareExpressionParser() {
    }

    public Expression parseExpression(String expressionString) throws ParseException {
        return this.parseExpression(expressionString, NON_TEMPLATE_PARSER_CONTEXT);
    }

    public Expression parseExpression(String expressionString, ParserContext context) throws ParseException {
        if (context == null) {
            context = NON_TEMPLATE_PARSER_CONTEXT;
        }

        return context.isTemplate() ? this.parseTemplate(expressionString, context) : this.doParseExpression(expressionString, context);
    }

    private Expression parseTemplate(String expressionString, ParserContext context) throws ParseException {
        if (expressionString.length() == 0) {
            return new LiteralExpression("");
        } else {
            Expression[] expressions = this.parseExpressions(expressionString, context);
            return (Expression)(expressions.length == 1 ? expressions[0] : new CompositeStringExpression(expressionString, expressions));
        }
    }

    private Expression[] parseExpressions(String expressionString, ParserContext context) throws ParseException {
        List<Expression> expressions = new LinkedList();
        String prefix = context.getExpressionPrefix();
        String suffix = context.getExpressionSuffix();
        int startIdx = 0;

        while(startIdx < expressionString.length()) {
            int prefixIndex = expressionString.indexOf(prefix, startIdx);
            if (prefixIndex >= startIdx) {
                if (prefixIndex > startIdx) {
                    expressions.add(this.createLiteralExpression(context, expressionString.substring(startIdx, prefixIndex)));
                }

                int afterPrefixIndex = prefixIndex + prefix.length();
                int suffixIndex = this.skipToCorrectEndSuffix(prefix, suffix, expressionString, afterPrefixIndex);
                if (suffixIndex == -1) {
                    throw new ParseException(expressionString, prefixIndex, "No ending suffix ‘" + suffix + "‘ for expression starting at character " + prefixIndex + ": " + expressionString.substring(prefixIndex));
                }

                if (suffixIndex == afterPrefixIndex) {
                    throw new ParseException(expressionString, prefixIndex, "No expression defined within delimiter ‘" + prefix + suffix + "‘ at character " + prefixIndex);
                }

                String expr = expressionString.substring(prefixIndex + prefix.length(), suffixIndex);
                expr = expr.trim();
                if (expr.length() == 0) {
                    throw new ParseException(expressionString, prefixIndex, "No expression defined within delimiter ‘" + prefix + suffix + "‘ at character " + prefixIndex);
                }

                expressions.add(this.doParseExpression(expr, context));
                startIdx = suffixIndex + suffix.length();
            } else {
                expressions.add(this.createLiteralExpression(context, expressionString.substring(startIdx)));
                startIdx = expressionString.length();
            }
        }

        return (Expression[])expressions.toArray(new Expression[expressions.size()]);
    }

    private Expression createLiteralExpression(ParserContext context, String text) {
        return new LiteralExpression(text);
    }

    private boolean isSuffixHere(String expressionString, int pos, String suffix) {
        int suffixPosition = 0;

        for(int i = 0; i < suffix.length() && pos < expressionString.length(); ++i) {
            if (expressionString.charAt(pos++) != suffix.charAt(suffixPosition++)) {
                return false;
            }
        }

        return suffixPosition == suffix.length();
    }

    private int skipToCorrectEndSuffix(String prefix, String suffix, String expressionString, int afterPrefixIndex) throws ParseException {
        int pos = afterPrefixIndex;
        int maxlen = expressionString.length();
        int nextSuffix = expressionString.indexOf(suffix, afterPrefixIndex);
        if (nextSuffix == -1) {
            return -1;
        } else {
            Stack stack;
            for(stack = new Stack(); pos < maxlen && (!this.isSuffixHere(expressionString, pos, suffix) || !stack.isEmpty()); ++pos) {
                char ch = expressionString.charAt(pos);
                switch(ch) {
                case ‘"‘:
                case ‘\‘‘:
                    int endLiteral = expressionString.indexOf(ch, pos + 1);
                    if (endLiteral == -1) {
                        throw new ParseException(expressionString, pos, "Found non terminating string literal starting at position " + pos);
                    }

                    pos = endLiteral;
                    break;
                case ‘(‘:
                case ‘[‘:
                case ‘{‘:
                    stack.push(new TemplateAwareExpressionParser.Bracket(ch, pos));
                    break;
                case ‘)‘:
                case ‘]‘:
                case ‘}‘:
                    if (stack.isEmpty()) {
                        throw new ParseException(expressionString, pos, "Found closing ‘" + ch + "‘ at position " + pos + " without an opening ‘" + TemplateAwareExpressionParser.Bracket.theOpenBracketFor(ch) + "‘");
                    }

                    TemplateAwareExpressionParser.Bracket p = (TemplateAwareExpressionParser.Bracket)stack.pop();
                    if (!p.compatibleWithCloseBracket(ch)) {
                        throw new ParseException(expressionString, pos, "Found closing ‘" + ch + "‘ at position " + pos + " but most recent opening is ‘" + p.bracket + "‘ at position " + p.pos);
                    }
                }
            }

            if (!stack.isEmpty()) {
                TemplateAwareExpressionParser.Bracket p = (TemplateAwareExpressionParser.Bracket)stack.pop();
                throw new ParseException(expressionString, p.pos, "Missing closing ‘" + TemplateAwareExpressionParser.Bracket.theCloseBracketFor(p.bracket) + "‘ for ‘" + p.bracket + "‘ at position " + p.pos);
            } else {
                return !this.isSuffixHere(expressionString, pos, suffix) ? -1 : pos;
            }
        }
    }

    protected abstract Expression doParseExpression(String var1, ParserContext var2) throws ParseException;

    private static class Bracket {
        char bracket;
        int pos;

        Bracket(char bracket, int pos) {
            this.bracket =

相关推荐