5.4.1 可拓展性实例

还说城堡游戏,通过封装,我们降低了类和类之间的耦合,虽然我们没有实现加入新的方向,但是我们为可拓展型,打下了非常好的基础。

因为,我们封装之前是Room的细节是直接曝光给Game的,Game是直接访问Room的四个成员变量来掌握方向的出口,现在我们把Room的变量都做成私有了,提供了两个接口,一个接口给出了文字描述,一个接口是返回一个指定方向的那个房间。

用接口来实现聚合

●给Room类实现的新方法,把方向的细节彻底隐藏在Room类内部了

●今后方向如何实现就和外部无关了


有了这两个函数来说,意味着对于外界来说,Room以为的其他部分来说,Room内部,如何去表达每一个出口,如何建立起出口方向的字符串和在那个出口对应的房间之间的关系,就是Room自己说了算。

我们现在还是使用成员变量表示四个方向,如果我们还想增加方向,就需要采用更加灵活的表示方向和房间之间的关系了。

接下来,我们用容器来实现灵活性

●Room的方向是用成员变量表示的,增加或减少方向都要改变代码

●如果用Hash表来表示方向,那么方向就不是“硬编码”的了。


那方向就和Room本身没有关系了,更加的灵活

我们还通过

HashMash<键值类型,存储类型>  容器名 = new  HashMap<键值类型,存储类型>();


public class Room {
    private HashMap<String,Room>  exits = new HashMap<String, Room>();
}

当然,我们设置方向和数据之间的关系之后,我们的Room自然会报错,我们就不需要传入地点再判断那个方向是否有房间了

你叉叉————> 

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

我们只要给出方向和房间就可以了,当我们创建了对象之后,谁调用它,那他就可以根据传入的方向,来存入对应对象的方向的房间信息。

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

	}

那接下来的输出接下来出口的方向的成员函数也对应变了,

你叉叉

 我们需要的是根据目前的房间,输出有出口的方向,我们需要输出的就是方向,也就是键值(键值就是方向,对应的元素就是方向上的房间)

我们需要拿到调用成员函数的容器键值,然后利用for-each循环,把方向存到StringBuffer就可以了

	public String getExitDesc(){
        StringBuffer   sb = new  StringBuffer();
        for( String dir : exits.keySet()){
                sb.append(dir);

                sb.append(' ');
        }
        return sb.toString();
	}

接下来调整:

Room的成员函数是 管理输出  位移后房间  的函数public Room getExits(String direction){}

我们只用利用HashMash容器就可以了,传入方向键值,调用容器就可以得到,那个方向的房间了

	public Room getExit(String direction){
		  return exits.get(direction);
	}

当然Room里面的成员函数内部虽然改变了,但是成员函数的名字没变,返回的参数也没变,所以Game调用Room,不受影响,唯一受影响的就是,我们改变了方向和房间的关系,所以在Game里创建对象,对对象进行关系赋值的时候会受影响,我们采用的是方向键值和那个方向的房间进行的匹配关系。

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

		lobby.setExit("up" , pub);

		pub.setExit("down" , lobby);

那这样,我们就可以任意添加任意房间任意方向房间信息了。

我们就加入了上下的对应关系,那我们加入上下的关系,就和Room没有任何关系了,反正都是一一对应的关系。这个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("城堡外");
        lobby = new Room("大堂");
        pub = new Room("小酒吧");
        study = new Room("书房");
        bedroom = 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);

		lobby.setExit("up" , pub);

		pub.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 = 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.println(currentRoom.getExitDesc());		        
		        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;

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 dir, Room room){
         exits.put(dir, room);

	}
    
    @Override
    public String toString()
    {
        return description;
    }
   
	public String getExitDesc(){
        StringBuffer   sb = new  StringBuffer();
        for( String dir : exits.keySet()){
                sb.append(dir);

                sb.append(' ');
        }
        return sb.toString();
	}

	public Room getExit(String direction){
		  return exits.get(direction);
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值