解释器模式
- 案例,实现四则运算,输入表达式,表达式的字母不能重复
- 编译原理中,一个算术表达式需要通过
词法分析器形成词法单元,这些词法通过语法分析器构建语法分析树。词法分析器和语法分析器都可以是解释器
- Interpreter Pattern,给定一个
语言表达式,定义文法和解释器,解释器用来解释语言中的句子
- 一些
重复出现的问题可以用一种简单的语言来表示,编译器、运算表达式、正则表达式

- 案例类图,将表达式拆成多个部分,
用不同的具体解释器去解释

- 表达式抽象类,Expression
public abstract class Expression {
public abstract int interpreter(HashMap<String, Integer> var);
}
public class VarExpression extends Expression {
private String key;
public VarExpression(String key) {
this.key = key;
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return var.get(this.key);
}
}
public class SymbolExpression extends Expression {
protected Expression left;
protected Expression right;
public SymbolExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpreter(HashMap<String, Integer> var) {
return 0;
}
}
public class AddExpression extends SymbolExpression {
public AddExpression(Expression left, Expression right) {
super(left, right);
}
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
public class SubExpression extends SymbolExpression {
public SubExpression(Expression left, Expression right) {
super(left, right);
}
public int interpreter(HashMap<String, Integer> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
- Calculator,计算类,将表达式转换为解释器类,最终通过
递归的方式得到答案
public class Calculator {
private Expression expression;
public Calculator(String expStr) {
Stack<Expression> stack = new Stack<>();
char[] charArray = expStr.toCharArray();
Expression left = null;
Expression right = null;
for (int i = 0; i < charArray.length; i++) {
switch (charArray[i]) {
case '+':
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new AddExpression(left, right));
break;
case '-':
left = stack.pop();
right = new VarExpression(String.valueOf(charArray[++i]));
stack.push(new SubExpression(left, right));
break;
default:
stack.push(new VarExpression(String.valueOf(charArray[i])));
break;
}
}
this.expression = stack.pop();
}
public int run(HashMap<String, Integer> var) {
return this.expression.interpreter(var);
}
}
public static void main(String[] args) throws IOException {
String expStr = getExpStr();
HashMap<String, Integer> var = getValue(expStr);
Calculator calculator = new Calculator(expStr);
System.out.println("结果" + expStr + "=" + calculator.run(var));
}
public static String getExpStr() throws IOException {
System.out.print("请输入表达式: ");
return (new BufferedReader(new InputStreamReader(System.in))).readLine();
}
public static HashMap<String, Integer> getValue(String expStr) throws IOException {
HashMap<String, Integer> map = new HashMap<>();
for (char ch : expStr.toCharArray()) {
if (ch != '+' && ch != '-') {
if (!map.containsKey(String.valueOf(ch))) {
System.out.print("请输入" + String.valueOf(ch) + "的值:");
String in = (new BufferedReader(new InputStreamReader(System.in))).readLine();
map.put(String.valueOf(ch), Integer.valueOf(in));
}
}
}
return map;
}
Spring源码

Expression为接口,有多个实现

- 根据不同的
parse对象返回不同的Expression对象
SpelExpressionParser的父类TemplateAwareExpressionParser
public Expression parseExpression(String expressionString, @Nullable ParserContext context) throws ParseException {
return context != null && context.isTemplate() ? this.parseTemplate(expressionString, context) : this.doParseExpression(expressionString, context);
}
doParseExpression真正由InternalSpelExpressionParser实现,返回SpelExpression对象
parseTemplate
private Expression parseTemplate(String expressionString, ParserContext context) throws ParseException {
if (expressionString.isEmpty()) {
return new LiteralExpression("");
} else {
Expression[] expressions = this.parseExpressions(expressionString, context);
return (Expression)(expressions.length == 1 ? expressions[0] : new CompositeStringExpression(expressionString, expressions));
}
}
小结
- 当一个语言需要解释执行,将语言中的句子表示为一个抽象语法树,拆成几类含义,用对应的解释器解释
- 可能引起类膨胀,采用递归调用
状态模式
- 每一次抽象扣除50积分,中奖概率为10%
- 奖品数量固定,抽完不能参加
- 有四个状态 可以抽奖、不能抽奖、发放奖品、奖品领完
- State Pattern,用来解决对象在多种状态转换时,需要对外输出不同的行为,
状态和行为是一一对应的,当内在状态改变时,允许改变其行为
- 每一个状态都是一个对象,行为都是独立的

- 案例类图

- 抽象类,规范了活动中的行为
public abstract class State {
public abstract void reducePoints();
public abstract boolean raffle();
public abstract void dispensePrize();
}
public class NoRaffleState extends State {
RaffleActivity activity;
public NoRaffleState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void reducePoints() {
System.out.println("扣除50积分");
activity.setState(activity.getCanRaffleState());
}
@Override
public boolean raffle() {
System.out.println("扣了积分才能抽奖");
return false;
}
@Override
public void dispensePrize() {
System.out.println("不能领奖品");
}
}
public class CanRaffleState extends State {
RaffleActivity activity;
public CanRaffleState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void reducePoints() {
System.out.println("已经扣过积分了");
}
@Override
public boolean raffle() {
System.out.println("正在抽奖");
Random r = new Random();
int num = r.nextInt(10);
if(num == 0){
activity.setState(activity.getDispenseState());
return true;
}else{
System.out.println("没有抽中奖品");
activity.setState(activity.getNoRafflleState());
return false;
}
}
@Override
public void dispensePrize() {
System.out.println("不能发放奖品");
}
}
public class DispenseState extends State {
RaffleActivity activity;
public DispenseState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void reducePoints() {
System.out.println("不能扣积分");
}
@Override
public boolean raffle() {
System.out.println("不能抽奖");
return false;
}
@Override
public void dispensePrize() {
int count = activity.getCount();
if (count == 1) {
System.out.println("恭喜中奖");
activity.setState(activity.getNoRafflleState());
System.out.println("奖品发完了");
activity.setState(activity.getFinishState());
System.out.println("活动结束");
System.exit(0);
} else {
System.out.println("恭喜中奖");
activity.setState(activity.getNoRafflleState());
}
}
}
public class FinishState extends State {
RaffleActivity activity;
public FinishState(RaffleActivity activity) {
this.activity = activity;
}
@Override
public void reducePoints() {
System.out.println("不能扣积分");
}
@Override
public boolean raffle() {
System.out.println("不能抽奖");
return false;
}
@Override
public void dispensePrize() {
System.out.println("不能发奖品");
}
}
public class RaffleActivity {
State state = null;
int count = 0;
State noRafflleState = new NoRaffleState(this);
State canRaffleState = new CanRaffleState(this);
State dispenseState = new DispenseState(this);
State finishState = new FinishState(this);
public RaffleActivity(int count) {
this.state = getNoRafflleState();
this.count = count;
}
public void redeucePoints(){
state.reducePoints();
}
public void raffle(){
if(state.raffle()){
state.dispensePrize();
}
}
public int getCount() {
int curCount = count;
count--;
return curCount;
}
}
借贷平台的应用
- 借贷平台的订单,有审核、发布、抢单的步骤,每个订单就会有多个状态
- 状态转移

- 类图

小结
- 可读性强,可维护性高,将每个状态的行为封装到类中,符合开闭原则
- 会产生很多类,每个状态都对应一个类,
- 适用于一个事件或对象有很多状态,状态之间会相互转换,不同的状态有不同的行为