消除代码复制的两个重要手段就是:父类和函数
评判一个程序是否优秀,主要是看类的设计
程序设计的目标是一系列通过明确的接口通信来协同工作的类。
在类的设计中,有两个重要的术语,耦合和聚合。
耦合:类与类之间的联系
我们要努力获得低的耦合度,因为在一个紧耦合的结构中,对一个类的修改也需要对其他类的修改,是一件既费时又易出错的事情。
聚合:一个代码单元应该负责一个聚合的任务
如果一个方法或类只负责一件定义明确的事情,那么就很有可能在另外不同的上下文环境中使用。
当程序某部分的代码需要改变时,在某个代码单元中很可能会找到所有需要改变的相关代码段。
再高层次的设计理念是优秀的代码要有可拓展性,
扫描二维码关注公众号,回复:
8730263 查看本文章
可扩展性:代码的某些部分不需要经过修改就能适应将来可能的变化。
翁恺老师太强辣!设计理念简直不要太棒,虽然看了几遍才懂
旧版本城堡游戏
package castle;
import java.util.Scanner;
public class Game {
private Room currentRoom;
public Game()
{
createRooms();
}
private void createRooms()
{
Room outside, lobby, pub, study, bedroom;
// 制造房间
outside = new Room("城堡外");
lobby = new Room("大堂");
pub = new Room("小酒吧");
study = new Room("书房");
bedroom = new Room("卧室");
// 初始化房间的出口
outside.setExits(null, lobby, study, pub);
lobby.setExits(null, null, null, outside);
pub.setExits(null, outside, null, null);
study.setExits(outside, bedroom, null, null);
bedroom.setExits(null, null, null, study);
currentRoom = outside; // 从城堡门外开始
}
private void printWelcome() {
System.out.println();
System.out.println("欢迎来到城堡!");
System.out.println("这是一个超级无聊的游戏。");
System.out.println("如果需要帮助,请输入 'help' 。");
System.out.println();
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();
}
// 以下为用户命令
private void printHelp()
{
System.out.print("迷路了吗?你可以做的命令有:go bye help");
System.out.println("如:\tgo east");
}
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;
}
if (nextRoom == null) {
System.out.println("那里没有门!");
}
else {
currentRoom = nextRoom;
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();
}
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Game game = new Game();
game.printWelcome();
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;
}
}
System.out.println("感谢您的光临。再见!");
in.close();
}
}
package castle;
public class Room {
public String description;
public Room northExit;
public Room southExit;
public Room eastExit;
public Room westExit;
public Room(String description)
{
this.description = description;
}
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;
}
@Override
public String toString()
{
return description;
}
}
改良版本,亮瞎你二十年单身的十英寸大狗眼
可拓展性一流
package castle;
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("bye", new HandlerBye(this));
handlers.put("help", new HandlerHelp(this));
handlers.put("go", new HandlerGo(this));
createRooms();
}
private void createRooms()
{
Room outside, lobby, pub, study, bedroom, balcony , wineCeller;
// 制造房间
outside = new Room("城堡外");
lobby = new Room("大堂");
pub = new Room("小酒吧");
study = new Room("书房");
bedroom = new Room("卧室");
balcony = new Room("阳台");
wineCeller = new Room("酒窖");
// 初始化房间的出口
outside.setExit("west", pub);
outside.setExit("east", lobby);
outside.setExit("south", study);
pub.setExit("east", outside);
lobby.setExit("east", outside);
study.setExit("north", outside);
study.setExit("east", bedroom);
bedroom.setExit("east", study);
lobby.setExit("up", balcony);
lobby.setExit("down", wineCeller);
balcony.setExit("down", lobby);
wineCeller.setExit("up", lobby);//酒窖哈哈
currentRoom = outside; // 从城堡门外开始
}
private void printWelcome() {
System.out.println();
System.out.println("欢迎来到城堡!");
System.out.println("这是一个超级无聊的游戏。");
System.out.println("如果需要帮助,请输入 'help' 。");
System.out.println();
showposition();
}
// 以下为用户命令
public void showposition()
{
System.out.println("你在" + currentRoom);
System.out.print("出口有: ");
System.out.println(currentRoom.getExitInfo());//接口不错,降低耦合
}
public void goRoom(String direction)
{
Room nextRoom = currentRoom.getExit(direction);//接口降低耦合
if (nextRoom == null) {
System.out.println("那里没有门!");
}
else {
currentRoom = nextRoom;
showposition();
}
}
//游戏运行代码
public void play()
{
Scanner in = new Scanner(System.in);
while ( true ) {
String line = in.nextLine();
String[] words = line.split(" ");//读入方式你学到了吗
String value = "";
Handler handler = handlers.get(words[0]);
if(words.length>1)//如果不是go,那么传进去空字符串并无大碍
{
value = words[1];
}
if(handler != null)
{
handler.docmd(value);
if(handler.isBye())
{
break;
}
}
}
in.close();
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Game game = new Game();
game.printWelcome();
game.play();
System.out.println("感谢您的光临。再见!");
}
}
package castle;
import java.util.HashMap;
public class Room {
private String description;
private HashMap<String, Room> exits = new HashMap<String, Room>();
public Room(String description)
{
this.description = description;
}
public void setExit(String direction , Room room)//做成框架,不用像以前那样必须弄成参数表
{
exits.put(direction, room);
}
@Override
public String toString()
{
return description;
}
public String getExitInfo()//接口降低与Game的耦合
{
StringBuffer sb = new StringBuffer();//学到了,Java中StringBuffer是类似于c++中存放String的vector
for(String direction : exits.keySet())//for-each 遍历表中可触及到的地方并加入到字符串中(感觉有点像BFS的第一层,但是这个高效多了哇)
{
sb.append(direction);
sb.append(' ');
}
return sb.toString();
}
public Room getExit(String direction)
{
return exits.get(direction);
}
}
package castle;
public class Handler {
protected Game game;
public Handler(Game game) {
this.game = game;
}
public void docmd(String word) {}
public boolean isBye()
{
return false;
}
}
package castle;
public class HandlerBye extends Handler{
public HandlerBye(Game game) {
super(game);
this.game = game;
}
@Override
public boolean isBye() {
return true;
}
}
package castle;
public class HandlerHelp extends Handler {
public HandlerHelp(Game game) {
super(game);
this.game = game;
}
@Override
public void docmd(String word) {
System.out.println("迷路了吗?你可以做的命令有:go bye help");
System.out.println("如:\tgo east");
}
}
package castle;
public class HandlerGo extends Handler {
public HandlerGo(Game game) {
super(game);
this.game = game;
}
@Override
public void docmd(String word) {
game.goRoom(word);
}
}
虽然是个无聊的小游戏,不过这个设计理念是很重要的
下面是运行结果
nice!