代码参考:https://github.com/implement-study/composite_demo
一. 组合模式
在我看来组合模式和装饰器模式的区别是:组合模式肚子里有一大堆同类的对象,而装饰器模式肚子里只有一个同类对象。
二. 类图
三. 代码分析
1. 中缀表达式转后缀表达式
其核心思想是新建一个操作符栈,遍历中缀表达式,当遇到操作符时,首先判断该操作符的优先级是否高于当前栈顶的操作符的优先级,如果高于,则入栈,否则一直弹出元素加入到中缀表达式中,直至当前栈顶元素的优先级地域该操作符的优先级。
具体而言:
- 当遇到
(
时,直接入栈 - 当遇到
)
时,弹出元素直到遇到(
- 当遇到
+
或-
, 一直弹出高优先级的运算符(+
,-
,*
,\
)加入到中缀表达式中,然后压入栈中。 - 当遇到
*
或/
,一直弹出高优先级的运算符(*
,\
,)加入到中缀表达式中,然后压入栈中。 - 遇到数字时,直接加入到中缀表达式中。
最后弹出栈中的元素放入到中缀表达式中。
注意
:使用java的LinkedList来模拟栈时,统一使用removeLast()和addLast()来模拟,不要混用pop()和push(),这两个操作都是操作LiinkedList的头元素的。
2. 计算值
得到后缀表达以后,接下来就是新建一个Expression栈,遍历中缀表达式
- 遇到符号时,从Expression栈中弹出左右元素,然后新建BinaryExpression对象压入栈中
- 遇到数字时,新建NumberExpression对象压入栈中。
组合模式通过定义统一的接口,将多项式的叶子节点(如常数项、变量项)和组合节点(如加法、乘法表达式)视为同一类对象。方便扩展。(其实到这里为止,并没有完全凸显组合模式的优点,如果再拓展到变量项将会有另一番感受)