解释器模式提供了评估语言的语法或表达式的方式。给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。
解释器接口:
public interface Interpreter {
int interpret();
}
加法解释器:
public class AddInterpreter implements Interpreter {
private Interpreter firstExpression, secondExpression;
public AddInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
this.firstExpression = firstExpression;
this.secondExpression = secondExpression;
}
@Override
public int interpret() {
return this.firstExpression.interpret() + this.secondExpression.interpret();
}
@Override
public String toString() {
return "+";
}
}
乘法解释器:
public class MultiInterpreter implements Interpreter {
private Interpreter firstExpression, secondExpression;
public MultiInterpreter(Interpreter firstExpression, Interpreter secondExpression) {
this.firstExpression = firstExpression;
this.secondExpression = secondExpression;
}
@Override
public int interpret() {
return this.firstExpression.interpret() * this.secondExpression.interpret();
}
@Override
public String toString() {
return "*";
}
}
数字解释器:
public class NumberInterpreter implements Interpreter {
private int number;
public NumberInterpreter(int number) {
this.number = number;
}
public NumberInterpreter(String number) {
this.number = Integer.valueOf(number);
}
@Override
public int interpret() {
return this.number;
}
}
操作工具类:
public class OperatorUtil {
public static boolean isOperator(String symbol) {
return (symbol.equals("+") || symbol.equals("*"));
}
public static Interpreter getExpressionObject(Interpreter firstExpression, Interpreter secondExpression, String symbol) {
if (symbol.equals("+")) {
return new AddInterpreter(firstExpression, secondExpression);
} else if (symbol.equals("*")) {
return new MultiInterpreter(firstExpression, secondExpression);
} else {
return null;
}
}
}
解析后缀表达式的类:
public class CJExpressionParser {
private Stack<Interpreter> stack = new Stack<>();
public int parse(String str) {
String[] strItemArray = str.split(" ");
for (String symbol : strItemArray) {
if (!OperatorUtil.isOperator(symbol)) {
Interpreter numberExpression = new NumberInterpreter(symbol);
stack.push(numberExpression);
System.out.println(String.format("入栈: %d", numberExpression.interpret()));
} else {
//是符号可以计算
Interpreter firstExpression = stack.pop();
Interpreter secondExpression = stack.pop();
Interpreter operator = OperatorUtil.getExpressionObject(firstExpression, secondExpression, symbol);
System.out.println(String.format("出栈: %d 和 %d", firstExpression.interpret(), secondExpression.interpret()));
int result = operator.interpret();
NumberInterpreter resultExpression = new NumberInterpreter(result);
stack.push(resultExpression);
System.out.println(String.format("阶段结果入栈: %d", resultExpression.interpret()));
}
}
int result = stack.pop().interpret();
return result;
}
}
测试类:
public class InterpreterTest {
public static void main(String[] args) {
String cjInputStr = "6 5 11 + *";
CJExpressionParser expressionParser = new CJExpressionParser();
int result = expressionParser.parse(cjInputStr);
System.out.println("解释器计算结果: " + result);
}
}
测试结果:
此时的UML图如下:
用户类(被观察者):
public class User extends Observable {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void send(Message m) {
System.out.println(this.name + " 发送了一条消息");
setChanged();
//将要传递的消息作为参数传入
notifyObservers(m);
}
}
群组类(观察者):
public class Group implements Observer {
@Override
public void update(Observable o, Object arg) {
User user = (User) o;
Message msg = (Message) arg;
System.out.println("群成员: " + user.getName() + "发送了一条消息, 消息内容为: " + msg.getContent());
}
}
消息类:
public class Message {
private String content;
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
测试类:
public class ObserverTest {
public static void main(String[] args) {
Group group = new Group();
Message msg = new Message();
msg.setContent("大家好, 我是来自地球的处女座男生");
User user = new User("大明");
//需要将观察者列表注册到被观察者里面
user.addObserver(group);
user.send(msg);
}
}
测试结果:
消息类:
public class Message {
private String content;
public Message(String content) {
this.content = content;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
观察者1类(直接在方法上加上注解即可):
public class DataObserver1 {
@Subscribe
public void fun1(String msg) {
System.out.println(this.getClass().getSimpleName() + "类的fun1()方法执行了...");
System.out.println(msg);
}
@Subscribe
public void fun2(Message msg) {
System.out.println(this.getClass().getSimpleName() + "类的fun2()方法执行了...");
System.out.println(msg.getContent());
}
}
观察者2类:
public class DataObserver2 {
@Subscribe
public void fun(Integer msg) {
System.out.println(this.getClass().getSimpleName() + "类的fun()方法执行了...");
System.out.println("Integer msg: " + msg);
}
}
测试类:
public class GuavaTest {
public static void main(String[] args) {
DataObserver1 observer1 = new DataObserver1();
DataObserver2 observer2 = new DataObserver2();
EventBus eventBus = new EventBus();
//将观察者注册到消息总线中
eventBus.register(observer1);
eventBus.register(observer2);
System.out.println("============ before unregister ============");
// 只有注册的参数类型为String的方法会被调用
eventBus.post(new Message("广播一条消息"));
eventBus.post(123);
eventBus.post("Hello World!");
System.out.println("============ after unregister ============");
eventBus.unregister(observer1); // 注销observer1
eventBus.post(new Message("再次广播一条消息"));
eventBus.post(123);
eventBus.post("Hello World!");
}
}
测试结果: