JAVA23种设计模式(4)-行为型模式11种2
1.策略模式(Strategy)
原理:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类具体设定行为对象.
//1.定义行为算法基类
public interface IDance {
void beginDance();
}
//2.定义Idance的子类1.不会跳舞
public class SimpleDance implements IDance {
@Override
public void beginDance() {
System.out.println("不会跳舞");
}
}
//3.定义行为算法Idance的子类2--探戈
public class TangoDance implements IDance {
@Override
public void beginDance() {
System.out.println("开始跳探戈了");
}
}
//4.定义基类ISwin 游泳的基类
public interface ISwin {
void beginSwin();
}
//5.定义不会游泳为Idance的子类1
public class SimpleSwin implements ISwin {
@Override
public void beginSwin() {
System.out.println("不会游泳");
}
}
//6.定义狗带式游泳为基类算法2
public class DogSwin implements ISwin {
@Override
public void beginSwin() {
System.out.println("狗带式游泳");
}
}
//7.开始定义使用者的基类,有两个接口作为成员变量
public class AbsHuman {
private IDance mDance;
private ISwin mSwin;
public AbsHuman()
{
mDance=new SimpleDance();
mSwin=new SimpleSwin();
}
//提供了公共方法去切换两个成员变量的实现
public void changeSwin(ISwin swin)
{
mSwin=swin;
}
public void changeDance(IDance dance)
{
mDance=dance;
}
//使用不同的展现
public void beginDance()
{
mDance.beginDance();
}
public void beginSwin()
{
mSwin.beginSwin();
}
}
//8.进行切换测试
public class Main {
public static void main(String[] args) {
AbsHuman human=new AbsHuman();
human.beginDance();
human.beginSwin();
System.out.println("___________________");
System.out.println("开始更换算法");
human.changeDance(new TangoDance());
human.changeSwin(new DogSwin());
human.beginDance();
human.beginSwin();
}
}
这个模式就体现对修改关闭,对扩展开放原则的开闭原则,当需求改动的时候,不要在原有代码上去进行注释,写代码.而是我提供算法族的接口,用不同的实现类去切换.这就是非常简单的实现插件式的热拔插效果,这个模式非常有用,大家好好体会
2.命令模式(Command)
原理:将请求/命令/动作封装成对象,这样可以让项目使用这些对象来参数化其他对象,使命令的请求者和执行者可以解耦.
任何状况下,所能观察到得单元越小越具有拓展性,比如,我们研究化学只能在分子状态下得时候,那么我们基本还是属于实验化学去达成我们想要的化合物,但是当我们的研究深入到原子层面的时候,我们可以根据以往研究出来化学原理去探索生产新的化合物.
设计也是相同的道理,越是复杂的设计,越需要细小的单元,命令模式核心就是建立在细小单元完成的复杂设计.
//1.以"命令"作为单元的基类
public interface Command {
//每个命令有一个执行的方法
public void execute();
//同样,每个命令会有一个撤销的方法
public void undo();
}
//2. 命令单元的默认状态空实现是很有必要的,就像数字中的0,重要的状态
public class NoCommand implements Command {
@Override
public void execute() {
}
@Override
public void undo() {
}
}
//3.设定一个命令可以由多条命令组成的宏命令
public class MarcoCommand implements Command {
//用数组这种数据结构装下
private Command[] commands;
public MarcoCommand(Command[] commands) {
this.commands = commands;
}
//执行宏命令--也就是将数组每一条命令取出来一一执行
@Override
public void execute() {
for (int i = 0, len = commands.length; i < len; i++) {
commands[i].execute();
}
}
//撤销宏命令--也就是将数组每一条宏命令取出来一一撤销
@Override
public void undo() {
for (int i = commands.length - 1; i >= 0; i--) {
commands[i].undo();
}
}
}
//4.设定命令的单元的执行主体-"灯"
public class Light {
String loc = "";
public Light(String loc) {
this.loc = loc;
}
public void On() {
System.out.println(loc + " On");
}
public void Off() {
System.out.println(loc + " Off");
}
}
//5."关灯"的命令
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light)
{
this.light=light;
}
//执行当然就是关灯
@Override
public void execute() {
light.Off();
}
//撤销就是开灯
@Override
public void undo() {
light.On();
}
}
//6.开灯的命令
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light)
{
this.light=light;
}
//执行就是开灯
@Override
public void execute() {
// TODO Auto-generated method stub
light.On();
}
//撤销就是关灯
@Override
public void undo() {
light.Off();
}
}
//7.设定命令的第二个主体,有音量属性,开/关/提高/降低 等操作函数
public class Stereo {
private int volume = 0;
public void On() {
System.out.println("Stereo On");
}
public void Off() {
System.out.println("Stereo Off");
}
public void SetCd() {
System.out.println("Stereo SetCd");
}
public void SetVol(int vol) {
volume = vol;
System.out.println("Stereo volume=" + volume);
}
public int GetVol() {
return volume;
}
public void Start() {
System.out.println("Stereo Start");
}
}
//8.打开音响的命令
public class StereoOnCommand implements Command {
private Stereo setreo;
public StereoOnCommand(Stereo setreo)
{
this.setreo=setreo;
}
@Override
public void execute() {
setreo.On();
setreo.SetCd();
}
@Override
public void undo() {
setreo.Off();
}
}
//9.关闭音响的命令
public class StereoOffCommand implements Command {
private Stereo setreo;
public StereoOffCommand(Stereo setreo)
{
this.setreo=setreo;
}
@Override
public void execute() {
// TODO Auto-generated method stub
setreo.Off();
}
@Override
public void undo() {
// TODO Auto-generated method stub
setreo.On();
setreo.SetCd();
}
}
//10.增加音量的命令
public class StereoAddVolCommand implements Command {
private Stereo setreo;
public StereoAddVolCommand(Stereo setreo)
{
this.setreo=setreo;
}
@Override
public void execute() {
int vol= setreo.GetVol();
if(vol<11)
{
setreo.SetVol(++vol);
}
}
@Override
public void undo() {
int vol= setreo.GetVol();
if(vol>0)
{
setreo.SetVol(--vol);
}
}
}
//11.降低音量的命令
public class StereoSubVolCommand implements Command {
private Stereo setreo;
public StereoSubVolCommand(Stereo setreo)
{
this.setreo=setreo;
}
@Override
public void execute() {
int vol= setreo.GetVol();
if(vol>0)
{
setreo.SetVol(--vol);
}
}
@Override
public void undo() {
int vol= setreo.GetVol();
if(vol<11)
{
setreo.SetVol(++vol);
}
}
}
//12.使用遥控器--对操作单元进行操作,slot的遥控器哪个插口
public class CommandModeControl {
private Command[] onCommands;
private Command[] offCommands;
private Stack<Command> stack=new Stack<Command>();
public CommandModeControl()
{
//给了5个开启命令,5个关闭命令
onCommands=new Command[5];
offCommands=new Command[5];
//初始化的时候将空实现带入所有插口中
Command noCommand=new NoCommand();
for(int i=0,len=onCommands.length;i<len;i++)
{
onCommands[i]=noCommand;
offCommands[i]=noCommand;
}
}
//给每个插口带入命令,,对应一个开,一个关闭
public void setCommand(int slot,Command onCommand,Command offCommand)
{
onCommands[slot]=onCommand;
offCommands[slot]=offCommand;
}
public void onButton(int slot) {
onCommands[slot].execute();
stack.push(onCommands[slot]);
}
public void offButton(int slot) {
offCommands[slot].execute();
stack.push(offCommands[slot]);
}
//使用栈数据结构,好处,push多少个命令,就可以pop多少个命令,非常棒
public void undoButton() {
stack.pop().undo();
}
}
//13.这是命令模式的测试
public class ControlTest {
public static void main(String[] args) {
CommandModeControl control = new CommandModeControl();
//设定复杂命令的宏操作
MarcoCommand onmarco,offmarco;
//操作实体的灯以及开关
Light bedroomlight = new Light("BedRoom");
Light kitchlight = new Light("Kitch");
Stereo stereo = new Stereo();
//两个灯的开与关
LightOnCommand bedroomlighton = new LightOnCommand(bedroomlight);
LightOffCommand bedroomlightoff = new LightOffCommand(bedroomlight);
LightOnCommand kitchlighton = new LightOnCommand(kitchlight);
LightOffCommand kitchlightoff = new LightOffCommand(kitchlight);
//宏命令的开与关
Command[] oncommands={bedroomlighton,kitchlighton};
Command[] offcommands={bedroomlightoff,kitchlightoff};
onmarco=new MarcoCommand(oncommands);
offmarco=new MarcoCommand(offcommands);
//音响的开与关
StereoOnCommand stereoOn = new StereoOnCommand(stereo);
StereoOffCommand stereoOff = new StereoOffCommand(stereo);
StereoAddVolCommand stereoaddvol = new StereoAddVolCommand(stereo);
StereoSubVolCommand stereosubvol = new StereoSubVolCommand(stereo);
//开始为控制器的每个开关赋值,对应了5个插槽
control.setCommand(0, bedroomlighton, bedroomlightoff);
control.setCommand(1, kitchlighton, kitchlightoff);
control.setCommand(2, stereoOn, stereoOff);
control.setCommand(3, stereoaddvol, stereosubvol);
control.setCommand(4, onmarco, offmarco);
//这是进行操作
control.onButton(0);
control.undoButton();
//control.offButton(0);
control.onButton(1);
control.offButton(1);
control.onButton(2);
control.onButton(3);
control.offButton(3);
control.undoButton();
control.offButton(2);
control.undoButton();
control.onButton(4);
control.offButton(4);
}
}
即便不使用命令模式也可以做出上面的效果,但是使用命令模式的好处--
代码中的操作实体(灯,音响),命令(执行,撤销),控制器(插槽)都完全解耦了,如果进行拓展,或者修改,能将影响降低到最小
3.备忘录模式(Memento)
原理:在不破坏封装的前提下,存储关键对象的重要状态,从而可以在将来把对象还原到存储的那个状态
具体就是定义一个Memonto接口,然后用一个MementoManager去管理这个接口,随后不管什么样的使用场景,都到MementoManager这个缓冲进行保存.
//1.定义一个备忘录接口
public interface MementoInterface {
}
//2.定义备忘录管理类,作为缓冲保留着,另外这个缓冲在初始化程序的时候需要加载
public class MementoManager {
private HashMap<String,MementoInterface> mementoMap;
public MementoManager()
{
mementoMap=new HashMap<String,MementoInterface>();
}
//保存备忘录
public void saveMemonto(String name, MementoInterface memento) {
this.mementoMap.put(name, memento);
}
//提取备忘录
public MementoInterface retrieveMemento(String key)
{
return mementoMap.get(key);
}
//TODO 方法1 程序初始化的时候 需要从本地将持久化数据读出
//TODO 方法2 程序结束的时候 需要将缓存中的数据持久化到本地哦
}
//3.使用场景A中保存状态的备忘录
public class Studio_A_Memento implements MementoInterface{
private TreeMap<String,String> state;
public Studio_A_Memento(TreeMap<String,String> save)
{
state=new TreeMap<String,String>(save);
}
public TreeMap<String,String> getState()
{
return state;
}
public void setState(TreeMap<String,String> save)
{
state=save;
}
}
//4.使用场景A 的状态 打包备忘录,解包备忘录
public class User_Studio_A {
private TreeMap<String, String> state;//状态
public User_Studio_A()
{
state=new TreeMap<String, String>();
}
//将状态打包成一个备忘录
public MementoInterface createMemento()
{
return new Studio_A_Memento(state);
}
//从备忘录中获得状态
public void restoreMemento(MementoInterface memento)
{
state=((Studio_A_Memento)memento).getState();
}
public void showState() {
System.out.println("now state:" + state.toString());
}
//测试状态增加1
public void testState1() {
state.put("blood", "500");
state.put("progress", "gate1 end");
state.put("enemy", "5");
}
//测试状态增加2
public void testState2() {
state.put("blood", "450");
state.put("progress", "gate3 start");
state.put("enemy", "3");
}
}
//5.使用场景B中保存状态的备忘录
public class Studio_B_Memento implements MementoInterface {
private ArrayList<String> state;
public Studio_B_Memento(ArrayList<String> save) {
state = new ArrayList<String>(save);
}
public ArrayList<String> getState() {
return state;
}
public void setState(ArrayList<String> save) {
state = save;
}
}
//6.使用场景B 的状态 打包备忘录,解包备忘录
public class User_Studio_B {
private ArrayList<String> state;
public User_Studio_B()
{
state=new ArrayList<String>();
}
//将状态打包成一个备忘录
public MementoInterface createMemento()
{
return new Studio_B_Memento(state);
}
//从备忘录中获得状态
public void restoreMemento(MementoInterface memento)
{
state=((Studio_B_Memento)memento).getState();
}
public void testState1() {
state = new ArrayList<String>();
state.add("blood:320");
state.add("progress:gate2 mid");
state.add("enemy:15");
}
public void testState2() {
state = new ArrayList<String>();
state.add("blood:230");
state.add("progress:gate8 last");
state.add("enemy:12");
}
public void showState() {
System.out.println("now state:" + state.toString());
}
}
优点:
1.状态存储在外面.不和关键对象混在一起,可以帮助维护内聚
2.提供容易实现的恢复能力
3.保持关键对象的数据封装
缺点:
1.资源消耗上备忘录对象会很昂贵
2.存储和恢复过程很耗时
适用场合:
必须保存一个对象在某一个时刻的(整体或部分)状态,在对象以外的地方,以后需要时恢复到先前的状态
4.状态模式(state)
原理:根据内部状态的变化,改变对象的行为,看起来好像是修改了类.
如果采用一般的方法去做,是在每个方法中使用switch()分支,根据不同的状态执行不同的语句,可是,假如在需要拓展的时候,就在switch中增加case,如果想要封装性更加良好.因此考虑将状态抽象出来成为接口.
//1.定义状态接口,实现类是各种状态下的售货机的行为
public interface State {
//插入硬币
void insertCoin();
//退换硬币
void getBackCoin();
//旋转把手
void turnCrank();
//放出可乐
void offerCoke();
//打印状态
void printState();
}
//2.定义一个自动售货机 出售可乐
public class ColaMachine {
//当前状态接口
private State currenState;
//当前可乐数量
private int count = 0;
//5种状态的实现类
State mSoldOutState;
State mOnReadyState;
State mHasCoin;
State mSoldState;
State mWinnerState;
public ColaMachine(int cou)
{
count=cou;
mSoldOutState = new SoldOutState(this);
mOnReadyState = new OnReadyState(this);
mHasCoin = new HasCoinState(this);
mSoldState = new SoldState(this);
mWinnerState = new WinnerState(this);
if (count > 0) {
currenState = mOnReadyState;
} else {
currenState = mSoldOutState;
}
}
public int getCount() {
return count;
}
public void setCurrenState(State currenState) {
this.currenState = currenState;
}
//提供4个方法给用户使用 投币,返回硬币,转动出货把手,检查状态
public void insertCoin() {
currenState.insertCoin();
}
public void returnCoin() {
currenState.getBackCoin();
}
public void turnCrank() {
currenState.turnCrank();
currenState.offerCoke();
}
public void printstate() {
currenState.printState();
}
//提供 给状态的各个实现类使用
void releaseCandy() {
if (count > 0) {
count = count - 1;
System.out.println("a cola rolling out!");
}
}
}
import java.util.Random;
//3.定义state接口实现类1.有硬币状态
public class HasCoinState implements State {
private ColaMachine mColaMachine;
public HasCoinState(ColaMachine colaMachine)
{
this.mColaMachine = colaMachine;
}
@Override
public void insertCoin() {
System.out.println("you can't insert another coin!");
}
@Override
public void getBackCoin() {
System.out.println("coin return!");
mColaMachine.setCurrenState(mColaMachine.mOnReadyState);
}
@Override
public void turnCrank() {
System.out.println("crank turn...!");
Random winnerRandom = new Random();
int winner = winnerRandom.nextInt(10);
if(winner==10){
mColaMachine.setCurrenState(mColaMachine.mWinnerState);
}
else
{
mColaMachine.setCurrenState(mColaMachine.mSoldState);
}
}
@Override
public void offerCoke() {
}
@Override
public void printState() {
System.out.println("***HasCoinState***");
}
}
//4.定义state接口实现类2. 准备状态
public class OnReadyState implements State {
private ColaMachine mColaMachine;
public OnReadyState(ColaMachine colaMachine)
{
this.mColaMachine = colaMachine;
}
@Override
public void insertCoin() {
System.out.println("you have inserted a coin,next,please turn crank!");
mColaMachine.setCurrenState(mColaMachine.mHasCoin);
}
@Override
public void getBackCoin() {
System.out.println("you haven't inserted a coin yet!");
}
@Override
public void turnCrank() {
System.out.println("you turned,but you haven't inserted a coin!");
}
@Override
public void offerCoke() {
}
@Override
public void printState() {
System.out.println("***OnReadyState***");
}
}
//5.状态接口的实现类3-卖完状态
public class SoldOutState implements State {
private ColaMachine mColaMachine;
public SoldOutState(ColaMachine colaMachine) {
this.mColaMachine = colaMachine;
}
// 卖完状态的插入硬币
@Override
public void insertCoin() {
System.out.println("you can't insert coin,the machine sold out!");
}
// 卖完状态的旋转把手
@Override
public void turnCrank() {
System.out.println("you turned,but there are no cola!");
}
// 卖完状态的拿回硬币
@Override
public void getBackCoin() {
System.out.println("you can't get coin back,the machine sold out!");
}
// 卖完状态下的无法提供可乐
@Override
public void offerCoke() {
}
// 卖完状态下的打印状态
@Override
public void printState() {
System.out.println("***SoldOutState***");
}
}
//6.状态接口的实现类4-正在出可乐状态状态
public class SoldState implements State {
private ColaMachine mColaMachine;
public SoldState(ColaMachine colaMachine) {
this.mColaMachine = colaMachine;
}
@Override
public void insertCoin() {
System.out.println("please wait!we are giving you a candy!");
}
@Override
public void getBackCoin() {
System.out.println("you haven't inserted a coin yet!");
}
@Override
public void turnCrank() {
System.out.println("we are giving you a candy,turning another get nothing,!");
}
@Override
public void offerCoke() {
mColaMachine.releaseCandy();
if (mColaMachine.getCount() > 0) {
mColaMachine.setCurrenState(mColaMachine.mOnReadyState);
} else {
System.out.println("Oo,out of candies");
mColaMachine.setCurrenState(mColaMachine.mSoldOutState);
}
}
@Override
public void printState() {
System.out.println("***SoldState***");
}
}
//7.状态接口的实现类5-赢家状态-有一定几率多出一个
public class WinnerState implements State {
private ColaMachine mColaMachine;
public WinnerState(ColaMachine colaMachine)
{
this.mColaMachine = colaMachine;
}
@Override
public void insertCoin() {
System.out.println("please wait!we are giving you a candy!");
}
@Override
public void getBackCoin() {
System.out.println("you haven't inserted a coin yet!");
}
@Override
public void turnCrank() {
System.out.println("we are giving you a candy,turning another get nothing,!");
}
@Override
public void offerCoke() {
mColaMachine.releaseCandy();
if (mColaMachine.getCount() == 0) {
mColaMachine.setCurrenState(mColaMachine.mSoldOutState);
} else {
System.out.println("you are a winner!you get another candy!");
mColaMachine.releaseCandy();
if (mColaMachine.getCount() > 0) {
mColaMachine.setCurrenState(mColaMachine.mOnReadyState);
} else {
System.out.println("Oo,out of candies");
mColaMachine.setCurrenState(mColaMachine.mSoldOutState);
}
}
}
@Override
public void printState() {
System.out.println("***WinnerState***");
}
}
//8.代码测试
public class Main {
public static void main(String[] args) {
ColaMachine machine=new ColaMachine(6);
machine.printstate();
machine.insertCoin();
machine.printstate();
machine.turnCrank();
machine.printstate();
machine.insertCoin();
machine.printstate();
machine.turnCrank();
machine.printstate();
}
}
从代码中可以看出,将一个耦合性很高的类,使用接口将它的状态从属性中解耦出来,变成一个可以拓展的体系.
5.解释器模式(interpreter)
解释器模式:定义一个语法,定义一个解释器,该解释器处理该语法句子,将某些复杂问题,表达为某种语法规则,然后构建解释器来处理这类句子.
这一般是遇到了大数据分析套用公式进行计算的情况下进行处理
计算模型一般需要解释的有两种符号:
1.数据
2.计算符
由于计算机无法理解人类看算式的优先级,这里采用逆波兰算法
import java.util.HashMap;
//1.定义符号表达式统一的抽象基类
public abstract class AbstractExpresstion {
//传入一列数据
public abstract Float interpreter(HashMap<String, Float> var);
}
import java.util.HashMap;
//2.变量的符号
public class VarExpresstion extends AbstractExpresstion {
private String key;
public VarExpresstion(String _key) {
this.key = _key;
}
//普通的变量就是 变量代表的数值
@Override
public Float interpreter(HashMap<String, Float> var) {
return var.get(this.key);
}
}
//3.符号的分支-运算符,在逆波兰运算中,运算符是终结符
public abstract class SymbolExpresstion extends AbstractExpresstion {
protected AbstractExpresstion left;
protected AbstractExpresstion right;
public SymbolExpresstion(AbstractExpresstion _left,
AbstractExpresstion _right) {
this.left = _left;
this.right = _right;
}
}
//4."+"符号的
public class AddExpresstion extends SymbolExpresstion {
public AddExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {
super(_left, _right);
}
@Override
public Float interpreter(HashMap<String, Float> var) {
return super.left.interpreter(var) + super.right.interpreter(var);
}
}
//5."-"符号
public class SubExpresstion extends SymbolExpresstion {
public SubExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {
super(_left, _right);
}
@Override
public Float interpreter(HashMap<String, Float> var) {
return super.left.interpreter(var) - super.right.interpreter(var);
}
}
//6."*"乘符号
public class MultiExpresstion extends SymbolExpresstion {
public MultiExpresstion(AbstractExpresstion _left,
AbstractExpresstion _right) {
super(_left, _right);
}
@Override
public Float interpreter(HashMap<String, Float> var) {
return super.left.interpreter(var) * super.right.interpreter(var);
}
}
//7."/" 除法符号
public class DivExpresstion extends SymbolExpresstion {
public DivExpresstion(AbstractExpresstion _left, AbstractExpresstion _right) {
super(_left, _right);
}
@Override
public Float interpreter(HashMap<String, Float> var) {
return super.left.interpreter(var) / super.right.interpreter(var);
}
}
//8.逆波兰算法-计算机可读懂的栈结构 右序算法
public class RPN {
private ArrayList<String> expression = new ArrayList<String>();// 存储中序表达式
private ArrayList<String> right = new ArrayList<String>();// 存储右序表达式
private AbstractExpresstion result;// 结果
// 依据输入信息创建对象,将数值与操作符放入ArrayList中
// 根据自定义字符为分界符进行拆分,并将结果进行封装提供对应方法进行遍历取值,
// StringTokenizer 方法不区分标识符、数和带引号的字符串,它们也不识别并跳过注释;该方法用途类似于split方法,
public RPN(String input) {
// 公式 a+b-c*d+e-f
StringTokenizer st = new StringTokenizer(input, "+-*/()", true);
while (st.hasMoreElements()) {
//中序表达式就这个 链表是: "a","+","b","-","c","*","d","+","e","-","f"
expression.add(st.nextToken());
}
}
// 将中序表达式转换为右序表达式
private void toRight() {
// 1.新建立一个缓存的栈
Stacks aStack = new Stacks();
// 2. 符号缓存
String operator;
// 3.栈指针 是 position
int position = 0;
while (true) {
if (Calculate.isOperator((String) expression.get(position))) {
//如果是1个操作符
if (aStack.top == -1 || ((String) expression.get(position)).equals("(")) {
//第一个字符存入缓存
aStack.push(expression.get(position));
} else {
if (((String) expression.get(position)).equals(")")) {
//如果栈顶不是
if (!((String) aStack.top()).equals("(")) {
operator = (String) aStack.pop();
right.add(operator);
}
} else {
if (Calculate.priority((String) expression.get(position)) <= Calculate.priority((String) aStack.top()) && aStack.top != -1) {
operator = (String) aStack.pop();
if (!operator.equals("("))
right.add(operator);
}
aStack.push(expression.get(position));
}
}
} else //如果不是操作符,直接加入
right.add(expression.get(position));
position++;
//如果指针长度多于表达式
if (position >= expression.size())
break;
}
while (aStack.top != -1) {
operator = (String) aStack.pop();
right.add(operator);
}
}
// 对右序表达式进行求值(逆波兰求值)
public void getResult(HashMap<String, Float> var) {
this.toRight();
Stack<AbstractExpresstion> stack = new Stack<AbstractExpresstion>();
AbstractExpresstion op1, op2;
String is = null;
Iterator it = right.iterator();
while (it.hasNext()) {
is = (String) it.next();
if (Calculate.isOperator(is)) {
op2 = stack.pop();
op1 = stack.pop();
stack.push(Calculate.twoResult(is, op1, op2));
} else
stack.push(new VarExpresstion(is));
}
result = stack.pop();
it = expression.iterator();
while (it.hasNext()) {
System.out.print((String) it.next());
}
System.out.println("=" + result.interpreter(var));
}
// 计算工具类.
public static class Calculate {
// 判断是否为操作符号
public static boolean isOperator(String operator) {
if (operator.equals("+") || operator.equals("-") || operator.equals("*") || operator.equals("/")
|| operator.equals("(") || operator.equals(")"))
return true;
else
return false;
}
// 设置操作符号的优先级别
public static int priority(String operator) {
if (operator.equals("+") || operator.equals("-") || operator.equals("("))
return 1;
else if (operator.equals("*") || operator.equals("/"))
return 2;
else
return 0;
}
// 做2值之间的计算
public static AbstractExpresstion twoResult(String op, AbstractExpresstion a, AbstractExpresstion b) {
try {
AbstractExpresstion result = null;
if (op.equals("+"))
result = new AddExpresstion(a, b);
else if (op.equals("-"))
result = new SubExpresstion(a, b);
else if (op.equals("*"))
result = new MultiExpresstion(a, b);
else if (op.equals("/"))
result = new DivExpresstion(a, b);
else
;
return result;
} catch (NumberFormatException e) {
System.out.println("input has something wrong!");
return null;
}
}
}
// 栈类
public class Stacks {
private LinkedList list = new LinkedList();
int top = -1;
public void push(Object value) {
top++;
list.addFirst(value);
}
public Object pop() {
Object temp = list.getFirst();
top--;
list.removeFirst();
return temp;
}
public Object top() {
return list.getFirst();
}
}
}
//9.模拟一次运算
public class Calculator {
public Calculator() {
//随机生成大数据 3组 6个数据
float[][] dataSource = new float[3][6];
System.out.println("data source:");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 6; j++) {
dataSource[i][j] = (float) (Math.random() * 100);
System.out.print(dataSource[i][j] + ",");
}
System.out.println(";");
}
try {
System.out.println("Input a expression:");
BufferedReader is = new BufferedReader(new InputStreamReader(
System.in));
for (;;) {
String input = new String();
input = is.readLine().trim();
if (input.equals("q"))
break;
else {
//输入的公式带入逆波兰算法中
RPN boya = new RPN(input);
HashMap<String, Float> var;
for (int i = 0; i < 3; i++) {
var = new HashMap<String, Float>();
//三组 的 6个变量分别为a,b,c,d,e,f
var.put("a", dataSource[i][0]);
var.put("b", dataSource[i][1]);
var.put("c", dataSource[i][2]);
var.put("d", dataSource[i][3]);
var.put("e", dataSource[i][4]);
var.put("f", dataSource[i][5]);
//计算出结果
boya.getResult(var);
}
}
System.out
.println("Input another expression or input 'q' to quit:");
}
is.close();
} catch (IOException e) {
System.out.println("Wrong input!!!");
}
}
}
//10.测试一下
public class MainTest {
public static void main(String[] args) {
new Calculator();
}
}
优点:
1.容易修改,修改语法规则相应非终结符即可
2.托展方便,托展语法,只要增加非终结符即可.
缺点:
1.对于复杂语法的表示会产生复杂的类层次结构,不便管理和维护
2.解释器采用递归方式,效率会受影响
适用场合:
1.当你有一个简单语法,而且效率不是问题的时候
2.一些数据分析工具\报表设计工具\科学计算工具等
尽量不要在重要模块使用解释器模式,使用递归,内存开销比较大