Java 设计原则

 

一、城堡

1、

定义 Room 类。

定义了房子是什么,四个方向上的房子是什么。

package castle;

public class Room {
    public String description;//描述位置
    public Room northExit;//为什么是Room类型
    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) //4个方向房子是什么。
    {
        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.Scanner;

public class Game {
    private Room currentRoom;//目前房间
        
    public Game() 
    {
        createRooms();
    }

    private void createRooms()//房间初始化
    {
        Room outside, lobby, pub, study, bedroom;
      
        //	制造房间
        outside = new Room("城堡外");//初始对象,给description赋值
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        
        //	初始化房间的出口
        outside.setExits(null, lobby, study, pub);//outside周围的四个房间
        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;

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("城堡外");//初始对象,给description赋值
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        
        //	初始化房间的出口
        outside.setExits(null, lobby, study, pub);//outside连着三个房间
        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();
        showPrompt();
    }

    // 以下为用户命令
    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;//更新所在房间
            showPrompt();
        }
    }
    public void showPrompt() //到达一个房间后的输出选择
    {
    	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();
	}

}

将公共的提取出来,定义新的构造函数。  

三、封装

Room类

package castle;

public class Room {
    private String description;//描述位置
    private Room northExit;//???为什么是Room类型
    private Room southExit;
    private Room eastExit;
    private 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;
    }
    
    public String getExitDesc() // 得到出口  将Game中的输出移到Room
    {
//    	String ret="";  //这种方法开销大,每次都会产生一个新的String
//    	if(northExit!=null)
//    		ret+="north";
//    	if(eastExit!=null)
//    		ret+="east";
//    	if(westExit!=null)
//    		ret+="west";
//    	if(southExit!=null)
//    		ret+="south";
//    	return ret;
    	
    	StringBuffer sb=new StringBuffer();//这种方法开销小
    	if(northExit!=null)
    	    sb.append("north ");
		if(eastExit!=null)
			sb.append("east ");
		if(westExit!=null)
			sb.append("west ");
		if(southExit!=null)
			sb.append("south ");
		return sb.toString();
    }
    
    public Room selectNextRoom(String direction)//下一个房间
    {
    	Room nextRoom = null;
        if(direction.equals("north")) {
            nextRoom = this.northExit;
        }
        if(direction.equals("east")) {
            nextRoom = this.eastExit;
        }
        if(direction.equals("south")) {
            nextRoom = this.southExit;
        }
        if(direction.equals("west")) {
            nextRoom = this.westExit;
        }
        return nextRoom;
    }
    
}

Room中的对象变量全部为private。

黄的将出口信息返回,绿的将下一个房间的信息返回。蓝的给Room定义。

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("城堡外");//初始对象,给description赋值
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        
        //	初始化房间的出口
        outside.setExits(null, lobby, study, pub);//outside连着三个房间
        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();
        showPrompt();
    }

    // 以下为用户命令
    private void printHelp() 
    {
        System.out.print("迷路了吗?你可以做的命令有:go bye help");
        System.out.println("如:\tgo east");
    }

    private void goRoom(String direction) 
    {
        Room nextRoom;
        nextRoom=currentRoom.selectNextRoom(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());//调用Room类
        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();
	}

}

四、可扩展性

1、

Room类

package castle;

import java.util.HashMap;

public class Room {
    private String description;//描述位置
    private HashMap<String,Room> exist=new HashMap<String ,Room>();//HashMap 的键值对来存放,一间屋子里n个方向上的地方
    
    public Room(String description) 
    {
        this.description = description;
    }

    public void setExit(String dir,Room room)//往容器存放内容
    {
    	exist.put(dir,room);
    }

    @Override
    public String toString()
    {
        return description;
    }
    
    public String getExitDesc() // 得到容器中的出口(键)
    {
    	StringBuffer sb=new StringBuffer();//这种方法开销小
    	for(String dir:exist.keySet())//遍历键
    	{
    		sb.append(dir);
    		sb.append(" ");
    	}
		return sb.toString();
    }

    public Room selectNextRoom(String direction)//下一个房间
    {
        return exist.get(direction);//得到键对应的值
    }
    
}

2、Game类

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("城堡外");//初始对象,给description赋值
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        
        //	初始化房间的出口
        outside.setExit("east", lobby);//outside连着三个房间
        outside.setExit("south", study);
        outside.setExit("west",pub);
        lobby.setExit("west", outside);
        lobby.setExit("up", bedroom);//自由增加房间各个出口
        pub.setExit("west",outside);
        study.setExit("north",outside);
        study.setExit("east",bedroom);
        bedroom.setExit("west", study);
        bedroom.setExit("down", lobby);
        

        currentRoom = outside;  //	从城堡门外开始
    }

    private void printWelcome() {//初始欢迎信息
        System.out.println();
        System.out.println("欢迎来到城堡!");
        System.out.println("这是一个超级无聊的游戏。");
        System.out.println("如果需要帮助,请输入 'help' 。");
        System.out.println();
        showPrompt();
    }

    // 以下为用户命令
    private void printHelp() 
    {
        System.out.print("迷路了吗?你可以做的命令有:go bye help");
        System.out.println("如:\tgo east");
    }

    private void goRoom(String direction) 
    {
        Room nextRoom;
        nextRoom=currentRoom.selectNextRoom(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());//调用Room类
        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();
	}

}

本质上,是容器一一对应的关系。一个方向,定了一个房间。用容器来存放方向和房间。

五、框架+数据提高可扩展性

将go  bye  help 分别对应一个函数,也就是main()里只调用,而不输出。

5.1 定义一个父类,和三个子类来表示输出的函数

父类

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;
	}

}

bye子类

package castle;

public class HandlerBye extends Handler {

	public HandlerBye(Game game)//构造器
	{
		super(game);
	}
	@Override
	public boolean isBye() {
		// TODO Auto-generated method stub
		return true;
	}
	

}

help 子类

package castle;

public class HandlerHelp extends Handler {

	public HandlerHelp(Game game)//构造器
	{
		super(game);
	}
	@Override
	public void doCmd(String word) {
		 System.out.println("迷路了吗?你可以做的命令有:go bye help");
	     System.out.println("如:\tgo east");
	}
	

}

go 子类

package castle;

public class HandlerGo extends Handler {

	public HandlerGo(Game game)
	{
		super(game);
	}
	@Override
	public void doCmd(String word) {
		// TODO Auto-generated method stub
		game.goRoom(word);
	}
	

}

2、Room类

package castle;

import java.util.HashMap;

public class Room {
    private String description;//描述位置
    private HashMap<String,Room> exist=new HashMap<String ,Room>();
    
    public Room(String description) 
    {
        this.description = description;
    }

    public void setExit(String dir,Room room)
    {
    	exist.put(dir,room);
    }

    @Override
    public String toString()
    {
        return description;
    }
    
    public String getExitDesc() // 得到出口  将Game中的输出移到Room
    {
    	StringBuffer sb=new StringBuffer();//这种方法开销小
    	for(String dir:exist.keySet())
    	{
    		sb.append(dir);
    		sb.append(" ");
    	}
		return sb.toString();
    }
    
    public Room selectNextRoom(String direction)//下一个房间
    {
        return exist.get(direction);
    }
    
}

3、Game类

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>();//存放 (go help bye 所对应的Handler(game))函数定义为类。
        
    public Game() 
    {
    	handlers.put("go",new HandlerGo(this));//将go和Game对应
    	handlers.put("bye",new HandlerBye(this));
    	handlers.put("help",new HandlerHelp(this));
        createRooms();
    }

    private void createRooms()
    {
        Room outside, lobby, pub, study, bedroom;
      
        //	制造房间
        outside = new Room("城堡外");//初始对象,给description赋值
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = new Room("卧室");
        
        //	初始化房间的出口
        outside.setExit("east", lobby);//outside连着三个房间
        outside.setExit("south", study);
        outside.setExit("west",pub);
        lobby.setExit("west", outside);
        lobby.setExit("up", bedroom);
        pub.setExit("west",outside);
        study.setExit("north",outside);
        study.setExit("east",bedroom);
        bedroom.setExit("west", study);
        bedroom.setExit("down", lobby);
        
        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;
        nextRoom=currentRoom.selectNextRoom(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());//调用Room类
        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]);//得到 键words所对应的值(go help bye)得到的是game,已经对应起来了。
    		String value="";
    		if(words.length>1)
    			value=words[1];//help时,value是空的,区别go east、elp 和 bye
    		if(handler!=null) 
    		{
    			handler.doCmd(value);//有值时跳转HandlerGo,没有值时输出help
    			if (handler.isBye())
    				break;
    		}
    	}
    	System.out.println("感谢您的光临。再见!");
    	in.close();
    }
    
	public static void main(String[] args) {
		
		Game game = new Game();//新的游戏对象
		game.printWelcome();//输入初始欢迎信息
        game.play();
	}

}

 

posted on 2018-06-13 21:22  箬笠蓑衣  阅读(260)  评论(0编辑  收藏  举报