利用封装、继承对Java代码进行优化
2017-04-17 19:13
441 查看
利用封装、继承对Java代码进行优化
注:本文实例分别可以在oldcastle(未优化的代码)和newcastle(优化后的代码)中查看,网址见文末另:本文改编于MOOC上翁恺老师的课程,有兴趣的同学可以去看一看,课上的非常好。
城堡游戏:
城堡中有多个房间,用户通过输入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(); }
相关文章推荐
- 浅谈利用多态,继承和接口来封装代码,提高Java代码的可扩展性
- 利用继承进行JAVA的代码重用
- 利用java在服务器和客服端建立连接,进行通讯(代码实例)
- JAVAWEB开发之Hibernate详解(三)——Hibernate的检索方式、抓取策略以及利用二级缓存进行优化、解决数据库事务并发问题
- java基础学习记录之利用数组查表法进行进制转换优化的学习与练习七(十转二、十转八、十转十六)
- 对Java代码进行优化
- 深入java static关键字 在继承场景中jvm类加载器对其进行的优化
- 利用Idea 重构功能及Java8 优化深层嵌套代码
- java利用极光推送进行推送的代码
- 【Java】利用单例模式、可变参数优化Java操作Mysql数据库、JDBC代码的写作
- 目前的代码系统,一类的继承和方法的扩展为主的形式是否可以进行一种形式的优化?从而提升运行效率
- 背包问题 没有进行空间优化的java代码
- 利用java在服务器和客服端建立连接,进行通讯(代码实例)
- 利用朴素贝叶斯算法进行分类-Java代码实现
- Java中利用位与和位或进行函数参数优化的技巧
- Java 面向对象的三大特征:继承、封装【隐藏】、多态<为了适应需求的多种变化,使代码变得更加通用>
- JAVAWEB开发之Hibernate详解(三)——Hibernate的检索方式、抓取策略以及利用二级缓存进行优化、解决数据库事务并发问题
- java入门学习(6)—封装,继承,多态,this,super,初始代码块