23种设计模式下篇

行为型模式,共11种

 (1)责任链模式

 (2)策略模式

 (3)模板方法

 (4)状态模式

 (5)访问者模式

 (6)观察者模式

 (7)迭代器模式

 (8)命令模式

 (9)备忘录模式

 (10)中介者模式

(11)解释器模式

责任链模式

将接收者对象连成一条链,并在该链上传递请求对象,直到有一个接收者处理该请求对象。该请求对象事先不知道是由哪一个接收者对象处理的。

public abstract class PriceHandler {

    //直接后继,用于传递请求
    protected PriceHandler successor;
    
    public void setSuccessor(PriceHandler successor){
        this.successor = successor;
    }
    
    //处理折扣申请
    public abstract void processDiscount(float discount);

}

public class Sales extends PriceHandler {

    @Override
    public void processDiscount(float discount) {
        if(discount <= 0.05) {
            System.out.format("%s批准了折扣:%.2f
", this.getClass().getName(),discount);
        }
        else {
            successor.processDiscount(discount);
        }
    }

}

public class Manager extends PriceHandler {

    @Override
    public void processDiscount(float discount) {
        if(discount <= 0.3) {
            System.out.format("%s批准了折扣:%.2f
", this.getClass().getName(),discount);
        }
        else {
            successor.processDiscount(discount);
        }
    }

}

public class CEO extends PriceHandler {

    @Override
    public void processDiscount(float discount) {
        if(discount <= 0.5) {
            System.out.format("%s批准了折扣:%.2f
", this.getClass().getName(),discount);
        }
        else {
            System.out.format("%s拒绝了折扣:%.2f
", this.getClass().getName(),discount);
        }
    }

}

public class PriceHandlerFactory {

    //创建PriceHandler的工厂函数
    public static PriceHandler createPricHandler() {
        // TODO Auto-generated method stub
        PriceHandler sales= new Sales();
        PriceHandler manager= new Manager();
        PriceHandler ceo= new CEO();
        sales.setSuccessor(manager);
        manager.setSuccessor(ceo);
        return sales;
    }
}

public class Customer {
    
    private PriceHandler pricHandler;
    
    public void setPriceHandler(PriceHandler pricHandler) {
        this.pricHandler = pricHandler;
    }
    
    public void requestDiscount(float discount) {
        pricHandler.processDiscount(discount);
    }
    
}

public class MainClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Customer customer = new Customer();
        customer.setPriceHandler(PriceHandlerFactory.createPricHandler());
        Random rand = new Random();
        for(int i=0;i<10;i++) {
            System.out.print(i+":");
            customer.requestDiscount(rand.nextFloat());
        }
    }

}

策略模式

定义了不同的算法(策略),分别封装起来,让他们可以互相替换,即使算法变化了,也不会影响到使用算法的用户

//抽象策略
public interface Action {
    //学生的动作
    void action();
}

public class PlayAction implements Action {
    @Override
    public void action() {
        System.out.println("正在玩耍.......");
    }
}

public class SleepAction implements Action {
    @Override
    public void action() {
        System.out.println("正在睡觉......");
    }
}

public class Student {
    
    // 对策略的引用
    private Action action;

    public Student( Action action){
        this.action = action;
    }

    // 学生的行为
    public void studentAction(){
        action.action();
    }
    
}

public class MainClass {
    public static void main(String[] args) {
        // 睡觉的行为
        Action sleep = new SleepAction();
        // 玩的行为
        Action play = new PlayAction();
        
        //小明
        Student xiaoming = new Student(sleep);
        xiaoming.studentAction();
        //小明明
        Student mingming = new Student(play);
        mingming.studentAction();
    }
}

模板方法

一个算法框架涉及到很多步骤,把不变的部分封装在父类,可变的部分让不同的子类去实现,父类中可以包含默认的钩子方法,子类可以选择是否重写该钩子方法

//算法骨架
public abstract class RefreshBeverage {

    /*
     * 制备饮料的模板方法 封装了所有子类所遵循的算法框架
     */
    public final void prepareBeverageTemplate() {
        // 步骤一 将水煮沸
        boilWater();
        // 步骤二 泡制饮料
        brew();
        // 步骤三 将饮料倒入杯中
        pourInCup();
        if (isCustomerWantsCondiments()) {
            // 步骤四 加入调味料
            addCondiments();
        }
    }

    /*
     * Hook 钩子函数,提供一个空的或者默认的实现 子类重写该方法,可以自行决定是否挂钩以及如何挂钩
     */
    protected boolean isCustomerWantsCondiments() {
        return true;
    }

    // 因为将水煮沸和把饮料倒入杯中对所有子类是共同的行为,所以没必要向子类过多开放,所以方法定义为private,这样我们在进行子类编码时可以减少复杂度。
    // 这样不需要关注细枝末节,我们只需要关注我们特定业务的实现,这就是模板方法模式的好处。可以封装变与不变,将不变的固化在高层,隐藏其细节。
    private void boilWater() {
        System.out.println("将水煮沸");
    }

    private void pourInCup() {
        System.out.println("将饮料倒入杯中");
    }

    /*
     * 泡制饮料brew()和加入调料品addCondiments()这两个方法我们不知道它们在算法框架中的具体实现,因此定义为抽象方法,
     * 我们用protected进行修饰, 在子类中可见便于进行重写。
     */
    protected abstract void brew();

    protected abstract void addCondiments();

}

/**
 * 提供制备咖啡的具体实现子类。 具体子类实现延迟步骤,满足特定的业务需求。
 * 
 *
 */
public class Coffee extends RefreshBeverage {

    protected void brew() {
        System.out.println("步骤二 用沸水冲泡咖啡");
    }

    protected void addCondiments() {
        System.out.println("步骤四 加入糖和牛奶");
    }

}

public class Tea extends RefreshBeverage {

    protected void brew() {
        System.out.println("步骤二 用80度热水浸泡茶叶5分钟");
    }

    protected void addCondiments() {
        System.out.println("步骤四 加入柠檬");
    }

    protected boolean isCustomerWantsCondiments() {
        return false;
    }

}

public class MainClass {

    public static void main(String[] args) {
        System.out.println("制备咖啡中······");
        RefreshBeverage b1 = new Coffee();
        b1.prepareBeverageTemplate();
        System.out.println("咖啡好了········");

        // 制备茶的测试代码
        System.out.println("
*********************************");
        System.out.println("制备茶水中······");
        RefreshBeverage b2 = new Tea();
        b2.prepareBeverageTemplate();
        System.out.println("茶水好了······");
    }

}

状态模式

当一个对象的内在状态改变时允许改变其行为,可以简化if-else条件判断

//抽象的状态角色
public interface State {
    void handle();
}

public class FreeState implements State {

    @Override
    public void handle() {
        System.out.println("房间空闲!!!没人住!");
    }
}

public class CheckedInState implements State {

    @Override
    public void handle() {
        System.out.println("房间已入住!请勿打扰!");
    }

}

public class BookedState implements State {

    @Override
    public void handle() {
        System.out.println("房间已预订!别人不能预定!");
    }
}

public class ApartmentContext {
    
    private State state;
    
    public void setState(State s){
        this.state = s;
    }

    public State getState() {
        return state;
    }
    
    public void changeState(State s) {
        System.out.print("修改状态!==>   ");
        state = s;
        state.handle();
    }

}


public class MainClass {
    public static void main(String[] args) {
        // 获取房间对象
        ApartmentContext ctx = new ApartmentContext();
        // 设置房间状态
        ctx.changeState(new FreeState());
        ctx.changeState(new BookedState());
    }
}

访问者模式

对于数据结构稳定,而作用于数据结构的操作经常变化的时候,可以采用访问者模式,将数据结构和对数据的操作分离

//单个单子的接口(相当于Element)
public interface Bill {
 
    void accept(Viewer viewer);
 
}

//抽象单子类,一个高层次的单子抽象
public abstract class AbstractBill implements Bill{
 
    protected double amount;
 
    protected String item;
 
    public AbstractBill(double amount, String item) {
        super();
        this.amount = amount;
        this.item = item;
    }
 
    public double getAmount() {
        return amount;
    }
 
    public String getItem() {
        return item;
    }
 
}

//消费的单子
public class ConsumeBill extends AbstractBill{
 
    public ConsumeBill(double amount, String item) {
        super(amount, item);
    }
 
    public void accept(Viewer viewer) {
        if (viewer instanceof AbstractViewer) {
            ((AbstractViewer)viewer).viewConsumeBill(this);
            return;
        }
        viewer.viewAbstractBill(this);
    }
 
}

//收入单子
public class IncomeBill extends AbstractBill{
 
    public IncomeBill(double amount, String item) {
        super(amount, item);
    }
 
    public void accept(Viewer viewer) {
        if (viewer instanceof AbstractViewer) {
            ((AbstractViewer)viewer).viewIncomeBill(this);
            return;
        }
        viewer.viewAbstractBill(this);
    }
 
}

//超级访问者接口(它支持定义高层操作)
public interface Viewer{
 
    void viewAbstractBill(AbstractBill bill);
 
}

//比Viewer接口低一个层次的访问者接口
public abstract class AbstractViewer implements Viewer{
 
    //查看消费的单子
    abstract void viewConsumeBill(ConsumeBill bill);
 
    //查看收入的单子
    abstract void viewIncomeBill(IncomeBill bill);
 
    public final void viewAbstractBill(AbstractBill bill){}
}

//老板类,查看账本的类之一,作用于最低层次结构
public class Boss extends AbstractViewer{
 
    private double totalIncome;
 
    private double totalConsume;
 
    //老板只关注一共花了多少钱以及一共收入多少钱,其余并不关心
    public void viewConsumeBill(ConsumeBill bill) {
        totalConsume += bill.getAmount();
    }
 
    public void viewIncomeBill(IncomeBill bill) {
        totalIncome += bill.getAmount();
    }
 
    public double getTotalIncome() {
        System.out.println("老板查看一共收入多少,数目是:" + totalIncome);
        return totalIncome;
    }
 
    public double getTotalConsume() {
        System.out.println("老板查看一共花费多少,数目是:" + totalConsume);
        return totalConsume;
    }
 
}

//注册会计师类,查看账本的类之一,作用于最低层次结构
public class CPA extends AbstractViewer{
 
    //注会在看账本时,如果是支出,则如果支出是工资,则需要看应该交的税交了没
    public void viewConsumeBill(ConsumeBill bill) {
        if (bill.getItem().equals("工资")) {
            System.out.println("注会查看是否交个人所得税。");
        }
    }
    //如果是收入,则所有的收入都要交税
    public void viewIncomeBill(IncomeBill bill) {
        System.out.println("注会查看收入交税了没。");
    }
 
}

//财务主管类,查看账本的类之一,作用于高层的层次结构
public class CFO implements Viewer {
 
    //财务主管对每一个单子都要核对项目和金额
    public void viewAbstractBill(AbstractBill bill) {
        System.out.println("财务主管查看账本时,每一个都核对项目和金额,金额是" + bill.getAmount() + ",项目是" + bill.getItem());
    }
 
}

//账本类(相当于ObjectStruture)
public class AccountBook {
    //单子列表
    private List<Bill> billList = new ArrayList<Bill>();
    //添加单子
    public void addBill(Bill bill){
        billList.add(bill);
    }
    //供账本的查看者查看账本
    public void show(Viewer viewer){
        for (Bill bill : billList) {
            bill.accept(viewer);
        }
    }
}

public class MainClass {
 
    public static void main(String[] args) {
        AccountBook accountBook = new AccountBook();
        //添加两条收入
        accountBook.addBill(new IncomeBill(10000, "卖商品"));
        accountBook.addBill(new IncomeBill(12000, "卖广告位"));
        //添加两条支出
        accountBook.addBill(new ConsumeBill(1000, "工资"));
        accountBook.addBill(new ConsumeBill(2000, "材料费"));
 
        Viewer boss = new Boss();
        Viewer cpa = new CPA();
        Viewer cfo = new CFO();
 
        //两个访问者分别访问账本
        accountBook.show(cpa);
        accountBook.show(boss);
        accountBook.show(cfo);
 
        ((Boss) boss).getTotalConsume();
        ((Boss) boss).getTotalIncome();
    }
}

观察者模式

在对象之间定义了一对多的依赖,当一个对象改变状态,依赖它的对象会收到通知并自动更新

/***
 * 抽象被观察者接口
 * 声明了添加、删除、通知观察者方法
 * @author jstao
 *
 */
public interface Observerable {
    
    public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
    
}

/**
 * 被观察者,也就是微信公众号服务
 * 实现了Observerable接口,对Observerable接口的三个方法进行了具体实现
 * @author jstao
 *
 */
public class WechatServer implements Observerable {
    
    //注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
    private List<Observer> list;
    private String message;
    
    public WechatServer() {
        list = new ArrayList<Observer>();
    }
    
    @Override
    public void registerObserver(Observer o) {
        
        list.add(o);
    }
    
    @Override
    public void removeObserver(Observer o) {
        if(!list.isEmpty()) {
             list.remove(o);
        }
           
    }

    //遍历
    @Override
    public void notifyObserver() {
        for(int i = 0; i < list.size(); i++) {
            Observer oserver = list.get(i);
            oserver.update(message);
        }
    }
    
    public void setInfomation(String s) {
        this.message = s;
        System.out.println("微信服务更新消息: " + s);
        //消息更新,通知所有观察者
        notifyObserver();
    }

}

/***
 * 抽象观察者
 * 定义了一个update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。
 * @author jstao
 *
 */
public interface Observer {
    public void update(String message);
}

/**
 * 观察者
 * 实现了update方法
 * @author jstao
 *
 */
public class User implements Observer {

    private String name;
    private String message;
    
    public User(String name) {
        this.name = name;
    }
    
    @Override
    public void update(String message) {
        this.message = message;
        read();
    }
    
    public void read() {
        System.out.println(name + " 收到推送消息: " + message);
    }
    
}

public class MainClass {
    
    public static void main(String[] args) {
        WechatServer server = new WechatServer();
        
        Observer userZhang = new User("ZhangSan");
        Observer userLi = new User("LiSi");
        Observer userWang = new User("WangWu");
        
        server.registerObserver(userZhang);
        server.registerObserver(userLi);
        server.registerObserver(userWang);
        server.setInfomation("PHP是世界上最好用的语言!");
        
        System.out.println("----------------------------------------------");
        server.removeObserver(userZhang);
        server.setInfomation("JAVA是世界上最好用的语言!");
        
    }
}

迭代器模式

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示 

//迭代器接口 , 相当与jdk中的iterator
public interface MyIterator {
    boolean hasNext();
    Object next();
}


//标识接口是可以迭代的,返回一个迭代器,相当与jdk中的iterable
public interface MyIterable {

    MyIterator getMyIterator();
}

//具体的聚合对象,相当于ArrayList,HashMap等
public class PlaceContainer implements MyIterable {
    private String[] places;

    public PlaceContainer(String[] places) {
        this.places = places;
    }

    private class PlaceIterator implements MyIterator {
        private int index;

        @Override
        public boolean hasNext() {
            return index < places.length;
        }

        @Override
        public Object next() {
            return places[index++];
        }
    }

    @Override
    public MyIterator getMyIterator() {
        return new PlaceIterator();
    }

}

public class MainClass {

    public static void main(String[] args) {
        String[] places = new String[] { "beijing", "tianjin", "xian", "shanghai", "guangzhou" };
        PlaceContainer placeContainer = new PlaceContainer(places);
        for (MyIterator iterator = placeContainer.getMyIterator(); iterator.hasNext();) {
            System.out.println(iterator.next());
        }
    }
}

 命令模式

 将请求发送者与接收者解耦,请求发送者通过命令对象来间接引用请求接收者,也可以实现命令的取消和重做

public interface Command {
    //执行命令对应的操作
    public void execute();
    //执行撤销命令那个对应的操作
    public void undo();
}

public class AddCommand  implements Command{
    //持有接收者对象   
    private Operation  operation = null;
    //操作的数据,就是要加上的数据
    private int num;
    
    public void execute(){
        this.operation.add(num);
    }
    
    public void undo(){
        this.operation.add(-num);
    }
    
    public AddCommand(Operation operation,int num){
        this.operation = operation;
        this.num = num;
    }
}

public class SubstractCommand implements Command {
    private Operation operation = null;
    private int num;
    
    public SubstractCommand(Operation operation,int num){
        this.operation = operation;
        this.num = num;
    }
    @Override
    public void execute() {
         this.operation.substract(num);
    }
 
    @Override
    public void undo() {
         this.operation.substract(-num);
    }
 
}

//请求接收者
public class Operation {
    
    private int result ;
    public int getResult() {
        return result;
    }
 
    public void setResult(int result) {
         this.result = result;
    }
 
    public void add(int num) {
         result += num;
    }
 
    public void substract(int num) {
         result -= num;
    }
 
}

//请求发送者
public class Caculator {
    private Command addCommand = null;
    
    private Command substractCommand = null;
    
    private List<Command> undoCommands  = new ArrayList<Command>();
    
    private List<Command> redoCommands  = new ArrayList<Command>();
    
    public void setAddCommand(Command addCmd){
        this.addCommand = addCmd;
    }
    
    public void setSubstractCommand(Command substractCmd){
        this.substractCommand = substractCmd;
    }
    
    
    public void addPressed(){
        this.addCommand.execute();
        undoCommands.add(this.addCommand);
    }
    
    public void substractPressed(){
        this.substractCommand.execute();
        undoCommands.add(this.substractCommand);
    }
    
    public void undoPressed(){
        if(this.undoCommands.size()>0){
            Command cmd = this.undoCommands.get(this.undoCommands.size()-1);
            cmd.undo();
            this.redoCommands.add(cmd);
            this.undoCommands.remove(cmd); 
        }else{
            System.out.println("没有课撤销的命令");
        }
    }
    
    public void redoPressed(){
        if(this.redoCommands.size()>0){
            Command cmd = this.redoCommands.get(this.redoCommands.size()-1);
            cmd.execute();
            this.undoCommands.add(cmd);
            this.redoCommands.remove(cmd);
        }else{
            System.out.println("没有课恢复的命令");
        }
    } 
}

public class MainClass {
 
    public static void main(String[] args) {
        
         Operation operation = new Operation();
         AddCommand addCmd = new AddCommand(operation,5);
         SubstractCommand subCmd = new SubstractCommand(operation,3);
         
         Caculator caculator = new Caculator();
         caculator.setAddCommand(addCmd);
         caculator.setSubstractCommand(subCmd);
         
         caculator.addPressed();
         caculator.substractPressed();
         System.out.println(operation.getResult());
         caculator.undoPressed();
         System.out.println(operation.getResult());
         caculator.redoPressed();
         System.out.println(operation.getResult());
         
    }
 
}

备忘录

获取一个对象的内部状态,保存该状态,这样以后就可以将该对象恢复至原先保存的状态

public class Memento {

    public static void main(String[] args) {
        // 发起人与负责人
        Sponsor sponsor = new Sponsor();
        // 设置内容
        sponsor.setText("abc");
        // 保存状态
        sponsor.createManager(1);
        // 修改内容
        sponsor.setText("abcd");
        // 保存状态
        sponsor.createManager(2);
        // 修改内容
        sponsor.setText("abcde");
        // 保存状态
        sponsor.createManager(3);

        // 回滚到版本1
        sponsor.callBackToVersion(1);
        System.out.println("第一个版本的内容是:" + sponsor.getText());
        // 回滚到版本2
        sponsor.callBackToVersion(3);
        System.out.println("第三个版本的内容是:" + sponsor.getText());

    }

}

// 发起者+负责人 能知道备忘录角色的具体类容,因为备忘录角色是它的私有类
class Sponsor {
    private String text;

    private Map<Integer, TextEdit> map = new HashMap<>();

    // 每次取出最新的版本
    private TextEdit getTextEdit(Integer version) {
        return map.get(version);
    }

    // 保存版本
    private void setTextEdit(TextEdit baby, Integer version) {
        map.put(version, baby);
    }

    // 保存状态
    public void createManager(Integer version) {
        TextEdit edit = new TextEdit(text);
        setTextEdit(edit, version);
    }

    // 回滚到指定版本
    public void callBackToVersion(Integer version) {
        text = getTextEdit(version).getText();
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    // 备忘录角色,被发起者私有
    // 注意:此类的所有属性都是私有
    private class TextEdit {
        private String text;

        private TextEdit(String text) {
            this.text = text;
        }

        private String getText() {
            return text;
        }
    }
}

 中介者模式

协作一组同事. 那些同事互相之间不会直接沟通, 而是通过中介者

//抽象中介者
public abstract class UnitedNations {

    protected List<Country> countries = new LinkedList<>();

    public void register(Country country) {
        countries.add(country);
    }

    public void remove(Country country) {
        countries.remove(country);
    }

    protected abstract void declare(Country country, String msg);
}

//具体中介者
class UnitedNationsSecurityCouncil extends UnitedNations {

    @Override
    protected void declare(Country country, String msg) {
        for (Country toCountry : countries) {
            if (!toCountry.equals(country)) {
                String name = country.getName();
                toCountry.receive(name + "平和的说: " + msg);
            }
        }
    }
}

//抽象同事
public abstract class Country {

    protected UnitedNations mediator;

    private String name;

    public Country(UnitedNations mediator, String name) {
        this.mediator = mediator;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    protected abstract void declare(String msg);

    protected abstract void receive(String msg);
}

//具体同事
class Iraq extends Country {

    public Iraq(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("伊拉克接收到: [" + msg + "]");
    }
}

//具体同事
class China extends Country {

    public China(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("中国接收到: [" + msg + "]");
    }
}

//具体同事
class USA extends Country {

    public USA(UnitedNations mediator, String name) {
        super(mediator, name);
    }

    @Override
    public void declare(String msg) {
        mediator.declare(this, msg);
    }

    @Override
    public void receive(String msg) {
        System.out.println("美国接收到: [" + msg + "]");
    }
}

public class  MainClass {
 
    public static void main(String[] args) {
UnitedNations mediator
= new UnitedNationsSecurityCouncil(); Country usa = new USA(mediator, "美国"); Country china = new China(mediator, "中国"); Country iraq = new Iraq(mediator, "伊拉克"); mediator.register(usa); mediator.register(china); mediator.register(iraq); usa.declare("我要打伊拉克, 谁管我跟谁急!!!"); System.out.println("----------"); china.declare("我们强烈谴责!!!"); System.out.println("----------"); iraq.declare("来呀, 来互相伤害呀!!!"); } }

 

解释器模式

按照规定语法进行语句的解析并得到结果

public interface Expression {
    int interpreter(Context context);//
}

public abstract class NonTerminalExpression implements Expression {
    Expression e1, e2;

    public NonTerminalExpression(Expression e1, Expression e2) {

        this.e1 = e1;
        this.e2 = e2;
    }
}

public class MinusOperation extends NonTerminalExpression {

    public MinusOperation(Expression e1, Expression e2) {
        super(e1, e2);
    }

    // 将两个表达式相减
    @Override
    public int interpreter(Context context) {
        return e1.interpreter(context) - e2.interpreter(context);
    }
}

public class PlusOperation extends NonTerminalExpression {

    public PlusOperation(Expression e1, Expression e2) {
        super(e1, e2);
    }

    // 将两个表达式相加
    @Override
    public int interpreter(Context context) {
        return e1.interpreter(context) + e2.interpreter(context);
    }
}

public class TerminalExpression implements Expression {

    String variable;

    public TerminalExpression(String variable) {
        this.variable = variable;
    }

    @Override
    public int interpreter(Context context) {
        return Integer.valueOf(variable);
    }
}

public class Context {
    private Map<Expression, Integer> map = new HashMap<>();

    public void add(Expression s, Integer value) {
        map.put(s, value);
    }

    public Integer lookup(Expression s) {
        return map.get(s);
    }

    // 构建语法树的主要方法
    public static Expression build(String str) {
        // 主要利用栈来实现
        Stack<Expression> objects = new Stack<>();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            // 遇到运算符号+号时候
            if (c == '+') {

                // 先出栈
                Expression pop = objects.pop();

                // 将运算结果入栈
                objects.push(new PlusOperation(pop, new TerminalExpression(String.valueOf(str.charAt(++i)))));
            } else if (c == '-') {
                // 遇到减号类似加号
                Expression pop = objects.pop();

                objects.push(new MinusOperation(pop, new TerminalExpression(String.valueOf(str.charAt(++i)))));

            } else {
                // 遇到非终结符直接入栈(基本就是第一个数字的情况)
                objects.push(new TerminalExpression(String.valueOf(str.charAt(i))));
            }
        }
        // 把最后的栈顶元素返回
        return objects.pop();
    }
}

public class MainClass {
    public static void main(String[] args) {
        String str = "4+8-2+9+9-8";
        Context context = new Context();
        Expression build = Context.build(str);
        System.out.println(str + " = " + build.interpreter(context));
    }
}
原文地址:https://www.cnblogs.com/moris5013/p/11562237.html