5.3.1 封装

本文讨论了如何通过封装和修改代码结构,降低Room和Game类之间的耦合,提高代码的可维护性和扩展性。作者强调了避免直接在Game类中调用Room成员变量的重要性,并提出了将出口判断和方向处理移至Room类的方法,以增强代码的清晰度和灵活性。
摘要由CSDN通过智能技术生成

上一个城堡游戏,没有bug ,可以运行,但不代表是好代码,衡量一个代码是不是好代码,要考虑

以后我们增加新功能的时候,是不是可以很快捷

增加可扩展性

●可以运行的代码 != 良好的代码

●对代码做维护的时候最能看出代码的质量

●如果想要增加一个方向,如down 或up

那这个程序,几乎是所有的部分,都要被你改掉,代码不具有可扩展性

用封装来降低耦合

•Room和Game类都有大量的代码和出口相关

•尤其是Game类中大量使用了Room类的成员变量

•类和类之间的关系称作耦合

•耦合越低越好,保持距离是形成良好代码的关键

有一个问题就是,Room里面的成员变量,我们说非不得已,不用Public,然而我们用了之后,

在Game里面一直重复调用Room里面的成员变量,我们说,这是不好的

所以,把Room里面的成员变量变成private 

 然而,改完之后,由于Game里面调用Room的成员变量不可访问了,

当然,这时候会有同学说,我们可以在Room里面为每个成员变量设置一个public 

的返回值的成员函数,然后在Game里面调用,这是一个无可奈何的做法。

 

我们现在要理解的是,为什么我们需要调用Room里面的成员函数,我们在Game里

面,要通过判断Room的成员变量是否为空,从而判断那个方向是否有出口,那我们为什么不直接

返回有没有出口呢?这说明,我们没必要在Game类里重复调用Room里面的成员变量,直接

让Room返回Game想要的结果就可以了,把工厂搬出去,在源头生产,更方便。

所以,我们现在要做的就是,要把出口,全部判断出来,并返回给Game

在Room里面,通过StringBuffer 来存储出口

创建成员变量

public String getExitDesc(){

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

}

那在Game里面判断出口的成员函数public void showPeompt(){}就改变了,就可以直接调用Room里面的成员函数,返回对应的参数就可以了

public void showPrompt(){

				System.out.println("现在你在" + currentRoom);
		        System.out.print("出口有:");
		        System.out.println(currentRoom.getExitDesc());		        
		        System.out.println();
	}

另外,我们在Game类里面,private void goRoom(String direction){  }里面

传入方向String direction,判断赋值下一个房间的时候,我们也重复调用了Room的成员变量,

同样我们让Room自己做这个事情,

我们在Room里面创建一个成员变量,根据传入的方向参数String direction,再调用自己的成员变量,返回给Game 对应方向的房间

public Room getExit(String direction){
		Room ret = null;
		if(direction.equals("north")){
			ret = northExit;
		}
		if(direction.equals("east")){
			ret = eastExit;
		}
		if(direction.equals("west")){
			ret = westExit;
		}
		if(direction.equals("south")){
			ret = southExit;
		}
		return ret;
	}

然后Game类,private void goRoom(){} 这个传入方向,出房间的成员函数就变了,它直接调用Room里面的成员函数,就可以得出下一个方向房间的信息了。

private void goRoom(String direction) 
    {
        Room nextRoom = currentRoom.getExit(direction);
        if (nextRoom == null) {
            System.out.println("那里没有门!");
        }
        else {
            currentRoom = nextRoom;
            showPrompt();
        }
    }

现在Game和Room直接就松了很多,这样,game就不会直接用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.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();
        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();
	}

}
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;
    }
	public String getExitDesc(){

        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 getExit(String direction){
		Room ret = null;
		if(direction.equals("north")){
			ret = northExit;
		}
		if(direction.equals("east")){
			ret = eastExit;
		}
		if(direction.equals("west")){
			ret = westExit;
		}
		if(direction.equals("south")){
			ret = southExit;
		}
		return ret;
	}
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值