利用封装、继承对Java代码进行优化
注:本文实例分别可以在oldcastle(未优化的代码)和newcastle(优化后的代码)中查看,网址见文末
城堡游戏:
城堡中有多个房间,用户通过输入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代码之美(11)---java代码的优化
java代码的优化 随着自己做开发时间的增长,越来越理解雷布斯说的: 敲代码要像写诗一样美.也能理解有一次面试官问我你对代码有洁癖吗? 一段好的代码会让人看就像诗一样,也像一个干净房间会让人看去很舒服 ...
- java代码(11) ---java代码的优化
java代码的优化 参考了一些Java开发手册有关代码的规范,觉得一段好的代码可以从三个维度去分析.1)性能,2)可扩展性,3)可读性 让我们看看别人是怎么去分析,还有值得我们去学习的地方,也是我正在 ...
- 35 个 Java 代码性能优化总结
前言 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用, ...
- Java 代码性能优化总结
前言 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用, ...
- Java代码性能优化总结
代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...
- Java 代码性能优化
代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是, ...
- 小细节,大用途,35 个 Java 代码性能优化总结!
前言: 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用 ...
- 来自极客头条的 35 个 Java 代码性能优化总结
前言 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用, ...
- 不得不看的Java代码性能优化总结
原文:https://blog.csdn.net/mr_smile2014/article/details/50112723 前言 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么 ...
随机推荐
- win7上Android环境搭建以及调试
工欲善其事必先利其器,好记性不如烂笔头.要学习一门新的语言,首先必须得先搭环境,否则没法实践.如果之前按照网上的提示,搭建过环境,而且环境比较复杂的话,我相信隔很长一段时间后,就会忘记,到真正用的时候 ...
- session、cookie与“记住我的登录状态”的功能的实现
Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...
- Java集合基本概念及元素添加
Java容器类类库的用途是"保存对象", 并将其划分为两个不同的概念: (1)Collection: 一个独立元素的序列, 这些元素都服从一条或多条规则. List必须按照插入的顺 ...
- Win 及 Linux 查找mac地址的方法
1. Windows系统中 - 调出cmd命令行 - 运行Getmac命令.命令行中输入: getmac /v /fo list 并按下回车键 - 查找物理地址.这是MAC地址的另一种描述方式.因为在 ...
- 【iOS】Core Bluetooth
本文介绍蓝牙4.0的一些基本知识. 基本概念.服务器.客户端 蓝牙LE是一个基于点对点的通信系统,其中一台设备作为服务器,另一台设备作为客户端.拥有数据的设备作为服务器,消费数据的设备作为客户端. 比 ...
- Eclipse设置新建jsp文件默认模板
没有需求就没有进步,遇到问题:现在有大量的html模板页面,但是这些模板是不能和后台进行数据交互的,所以要把他们通通变成jsp页面(59个html文件),还有就是html文件转换成jsp文件的时候,前 ...
- python列表操作符
list1=[123,456] list2=[234,234] list1>list2 >>>False#返回False 第一项比较之后直接返回false,第二项不看 #+实现 ...
- Mycat 安装与启动
环境准备 安装JDK1.8(必须JDK1.7及更高版本) 安装MySQL 服务安装与说明 下载 MyCAT 编译好的安装包,下载地址为 http://dl.mycat.io/1.6-RELEASE/ ...
- Nginx目录浏览功能
要给其他人提供一个patch的下载地址,于是想用nginx的目录浏览功能来做,需要让其他人看到指定一个目录下的文件列表,然后让他自己来选择该下载那个文件:效果如图. 实现步骤:在虚拟主机配置文件里面开 ...
- [poj2002]Squares_hash
Squares poj-2002 题目大意:在笛卡尔坐标系中给出n个点,求这些点可以构成多少个正方形. 注释:$1\le n\le 10^3$,$-2\cdot 10^3\le x , y\le 2\ ...