行为型设计模式---解释器模式和观察者模式

一、解释器模式

       解释器模式提供了评估语言的语法或表达式的方式。给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。


手动模拟后缀表达式(也叫逆波兰表达式)的例子。

       解释器接口:

	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);
	    }
	}

       测试结果:

Alt


       此时的UML图如下:

Alt




二、观察者模式

1、基于JDK的观察者模式

       用户类(被观察者):

	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);
	    }
	}

       测试结果:

Alt



2、基于Guava的观察者模式

       消息类:

	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!");
	    }
	}

       测试结果:

Alt

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值