封装与可扩展性
我们的这个城堡游戏的代码是能远行的,一切功能都正常,也没发现bug
但是一个能够正常运行的代码,没有bug,不等于它就是一个好代码,
评价一个代码是否好,标准是多元的,并不是只有唯一一个能远行,没有办法就是标准,尤其这个代码,否适应于将来的需要,什么是将来的需要,将来就只有一种需要,就是维护,代码写出来不是跑一次,用用就好了,要考虑很长很长时间
增加扩展性
可以运行的代码!=良好的代码
对代码做维护的时候组能看出代码质量
如果想要增加一个方向,如果down或up
在这个程序中增加一个东西,你的程序基本上都要被改掉,你都代码没有可以扩展性,
可扩展性:你的代码是不是可以很大程度保持不变,以不变应将来的万变
用封装来降低耦合
Room类和Game类都有大量的代码和出口相关
尤其是Game类中大量使用了Room类的成员变量
类和类之间的关系称作耦合
耦合越低越好,保持距离是形成良好代码的关键
我们一开始讲类的设计的时候,你不管这么样的应该让你的成员变量都是私有的private,万不得已的时候才去做public
改完之后的Game类
public class Game { private Room currentRoom; 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(); } private void createRooms() { Room outside, lobby, pub, study, bedroom,bedroom1; // 制造房间 outside = new Room("城堡外"); lobby = new Room("大堂"); pub = new Room("小酒吧"); study = new Room("书房"); bedroom = new Room("卧室"); bedroom1 =new Room("次卧"); // 初始化房间的出口 outside.setExit("east",lobby); outside.setExit("south",study); outside.setExit("west",pub); lobby.setExit("west", outside); pub.setExit("east", outside); study.setExit("north",outside); study.setExit("east",bedroom); bedroom.setExit("west", study); bedroom.setExit("up", bedroom1); bedroom1.setExit("down", bedroom); currentRoom = outside; // 从城堡门外开始 } private void printWelcome() { System.out.println(); System.out.println("欢迎来到城堡!"); System.out.println("这是一个超级无聊的游戏。"); System.out.println("如果需要帮助,请输入 'help' 。"); System.out.println(); showPrompt(); } // 以下为用户命令 public void goRoom(String direction) { Room nextRoom = currentRoom.getExit(direction); if (nextRoom == null) { System.out.println("那里没有门!"); } else { currentRoom = nextRoom; showPrompt(); } } public void showPrompt() { System.out.println("现在你在" + currentRoom); System.out.print("出口有:"); System.out.print(currentRoom.getExitDesc()); System.out.println(); } public void play() { Scanner in=new Scanner(System.in); while ( true ) { String line = in.nextLine(); String[] words = line.split(" "); Handler handler =handlers.get(words[0]); String value =""; if(words.length>1) value = words[1]; if(handler !=null) { handler.doCmd(value); if(handler.isBye()) { break; } } } } public static void main(String[] args) { Scanner in = new Scanner(System.in); Game game = new Game(); game.printWelcome(); game.play(); System.out.println("感谢您的光临。再见!"); in.close(); } }
Room类
package demo02.clock.chengbao; import java.util.HashMap; import java.util.Scanner; public class Game { private Room currentRoom; 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(); } private void createRooms() { Room outside, lobby, pub, study, bedroom,bedroom1; // 制造房间 outside = new Room("城堡外"); lobby = new Room("大堂"); pub = new Room("小酒吧"); study = new Room("书房"); bedroom = new Room("卧室"); bedroom1 =new Room("次卧"); // 初始化房间的出口 outside.setExit("east",lobby); outside.setExit("south",study); outside.setExit("west",pub); lobby.setExit("west", outside); pub.setExit("east", outside); study.setExit("north",outside); study.setExit("east",bedroom); bedroom.setExit("west", study); bedroom.setExit("up", bedroom1); bedroom1.setExit("down", bedroom); currentRoom = outside; // 从城堡门外开始 } private void printWelcome() { System.out.println(); System.out.println("欢迎来到城堡!"); System.out.println("这是一个超级无聊的游戏。"); System.out.println("如果需要帮助,请输入 'help' 。"); System.out.println(); showPrompt(); } // 以下为用户命令 public void goRoom(String direction) { Room nextRoom = currentRoom.getExit(direction); if (nextRoom == null) { System.out.println("那里没有门!"); } else { currentRoom = nextRoom; showPrompt(); } } public void showPrompt() { System.out.println("现在你在" + currentRoom); System.out.print("出口有:"); System.out.print(currentRoom.getExitDesc()); System.out.println(); } public void play() { Scanner in=new Scanner(System.in); while ( true ) { String line = in.nextLine(); String[] words = line.split(" "); Handler handler =handlers.get(words[0]); String value =""; if(words.length>1) value = words[1]; if(handler !=null) { handler.doCmd(value); if(handler.isBye()) { break; } } } } public static void main(String[] args) { Scanner in = new Scanner(System.in); Game game = new Game(); game.printWelcome(); game.play(); System.out.println("感谢您的光临。再见!"); in.close(); } }
可扩展性
通过封装降低了耦合之后,虽然我们还没有直接实现这么加入新的方向up dwon
用接口类实现聚合
给Room类实现的新方法,把方向的细节彻底隐藏在Room类内部了
今后方向如何实现就和外部无关了
因为原本Room里面的细节是直接曝光给game是直接使用room里面的那个四个成员变量来掌握它的每个方向的出口,现在我们把room的这些成员变量都做成私有了,提供了两个接口,一个接口给出文字描述,一个接口可以根据方向来返回
用容器来实现灵活性
Room的方向是成员变量表示的,增加或减少方向就要改变代码
如果用Hash表来表示方向,那么方向就不是硬编码的了