对Java代码进行优化

来源:互联网 发布:万达影城知乎 编辑:程序博客网 时间:2024/05/21 23:00


城堡游戏

城堡中有多个房间,用户通过输入north, south, east, west等来确认去哪一个房间(此时窗口会有提示转到哪个房间),如果此时多出一个房间,需要使用up, down才能到达,修改代码则需要代码具有可扩展性,对原来的代码进行优化来实现这个功能。

优化前代码思路:

图片描述

优化变量使代码具有可扩展性

主要思想:

  • 将 Room 中变量全部变为 private 类型,使代码变得安全。
  • 利用 Hash 表将 方向 变量实现灵活性。
private HashMap<String, Room> exits = new HashMap<String, Room>();

本文 Hash 表用到的方法:

HashMap<Key, Value>HashMap.keySet()    // 返回所有的key值HashMap.put(K, V)    // 用于往HashMap中加元素HashMap.get(K)        // 返回对应的V值

利用封装降低代码间耦合性

主要思想:

​ 给 Room 类实现新方法,把方向的细节彻底隐藏在 Room 类内部,增添的方向与外部无关。

先看这段代码,在 Game 中出现了2次。

/*Game.java*//*在printWelcome, goRoom中需要显示当前和选择时*/System.out.println("现在你在" + currentRoom);System.out.print("出口有:");if(currentRoom.northExit != null)    System.out.print("north ");if(currentRoom.eastExit != null)    System.out.print("east ");if(currentRoom.southExit != null)    System.out.print("south ");if(currentRoom.westExit != null)    System.out.print("west ");System.out.println();

修改思路:

在 Game 类中 添加 显示出口的方法:

/*Game.java*/public void showPrompt(){      System.out.println("现在你在" + currentRoom);    System.out.print("出口有:");    /*打印所有出口,getExitDesc()是Room中记录出口的新方法*/    System.out.println(currentRoom.getExitDesc());        System.out.println();}

Room 类增加 getExitDesc() 方法:

/*Room.java*/public String getExitDesc() {    StringBuffer sb = new StringBuffer();    // StringBuffer类是字符串变量,常用于对字符串扩充和修改    for (String dir : exits.keySet()) {        // 遍历所有的方向        sb.append(dir);                        // 扩充操作        sb.append(' ');    }    return sb.toString();}

goRoom 中的转移房间代码与 Room 中 setExit 有极高的耦合性:

/*Game.java*/private void goRoom(String direction) {      Room nextRoom = null;    if (direction.equals("north")) {      nextRoom = currentRoom.northExit;    }    if (direction.equals("east")) {      nextRoom = currentRoom.eastExit;    }    if (direction.equals("south")) {      nextRoom = currentRoom.southExit;    }    if (direction.equals("west")) {      nextRoom = currentRoom.westExit;    }}/*Room.java*/public void setExits(Room north, Room east, Room south, Room west) {    if(north != null)      northExit = north;    if(east != null)      eastExit = east;    if(south != null)      southExit = south;    if(west != null)      westExit = west;}

修改思路

对 Room 类修改 setExit 方法,并增加 getExit 方法。

/*Room.java*//*     * 录入房间空间位置的方式改变,由原来的对一个房间的四个方向分别定义,改为对一个房间 * 自定义方向以及该方向上  的新房间,这样有利于增添上下以及新的位置,具有可扩展性。 */public void setExit(String dir, Room room) {    exits.put(dir, room);            // 向exit中添加元素}public Room getExit(String direction) {    return exits.get(direction);    // 返回对应的Room}

对 Room 修改之后对 goRoom 的修改就简单许多:

/*Game.java*/private void goRoom(String direction) {      Room nextRoom = null;    Room nextRoom = currentRoom.getExit(direction);}

以框架+数据以及继承提高可扩展性

对于 Game 类 main 方法存在这样一段代码:

public static void main(String[] args) {    while (true) {        String line = in.nextLine();        String[] words = line.split(" ");        if (words[0].equals("help")) {          game.printHelp();        } else if (words[0].equals("go")) {          game.goRoom(words[1]);        } else if (words[0].equals("bye")) {          break;        }    }}

思考:能否脱离 if-else 来实现用户的命令。

修改思路之创造新的类

定义一个 Handler 类来处理命令,用户命令分为 go , help , bye 三类,此时用 Hash 表来保存用户命令与 Handler 之间的关系,则 Handler 需要三个子类分别处理三种命令:

图片描述

/*Handler.java*/public class Handler {      /*为了解决在HandlerGO操作中需要用到main方法里game,在Handler中创建Game来记录Game.java里的game.*/    protected Game game;    public Handler(Game game){        this.game = game;    }    public void doCmd(String word) {    }    public boolean isBye() {        return false;    }    public boolean isHelp() {        return false;    }}/*HandlerGo.java*/public class HandlerGo extends Handler {    public HandlerGo(Game game) {        super(game);    }    @Override    public void doCmd(String word) {        game.goRoom(word);    }}/*HandlerHelp.java*/public class HandlerHelp extends Handler {    public HandlerHelp(Game game) {        super(game);    }    @Override    public boolean isHelp() {        return true;    }}/*HandlerBye.java*/public class HandlerBye extends Handler {    public HandlerBye(Game game) {        super(game);    }    @Override    public boolean isBye() {        return true;    }}
/*Game.java*//*用Hash表保存命令与Handler之间的关系*/private HashMap<String, Handler> handlers = new HashMap<String, Handler>();/*构造器需要做相应的变化*/public Game() {    handlers.put("go", new HandlerGo(this));    handlers.put("bye", new HandlerBye(this));    handlers.put("help", new HandlerHelp(this));    createRooms();}/*为命令操作创造新的方法*/public void play(){      Scanner in = new Scanner(System.in);    while (true) {        String line = in.nextLine();        String[] words = line.split(" ");        /*         * 利用Hash表<K, V>的特性,如果用户输入"help",通过handler.get()得出handler类型         * 下面这句就相当于:Handler handler = new HandlerHelp(this);         */        Handler handler = handlers.get(words[0]);        String value = "";        if(words.length > 1)              value = words[1];        if(handler != null)        {              /*此时handler为HandlerHelp型,没有value值*/            handler.doCmd(value);            if(handler.isBye())                  break;              /*HandlerHelp继承了Handler中的isHelp()方法并将其覆盖,此时handler.isHelp()返回true.*/            if(handler.isHelp())                  this.printHelp();        }    }}public static void main(String[] args) {    Game game = new Game();    game.printWelcome();    game.play();}
0 0
原创粉丝点击