zoukankan      html  css  js  c++  java
  • 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));
        }
    }
  • 相关阅读:
    调用 验证码
    始终居中的弹出层
    jq常用
    ThinkPHP redirect 方法
    session 的生成和删除
    1355:字符串匹配问题(strs)
    1348:【例49】城市公交网建设问题
    1357:车厢调度(train)
    1358:中缀表达式值(expr)
    1351:【例412】家谱树
  • 原文地址:https://www.cnblogs.com/moris5013/p/11562237.html
Copyright © 2011-2022 走看看