首先贴出未修改的代码

Game.java

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

Room.java

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;}@Overridepublic String toString(){return description;}
}

消除代码复制的两个基本手段,就是函数和父类。

代码复制是代码不良的一种体现

要评判某些设计比其他的设计优秀,就得定义一些在类的设计中重要的术语,以用来讨论 设计的优劣。对于类的设计来说,有两个核心术语:耦合和聚合。 耦合这个词指的是类和类之间的联系。之前的章节中提到过,程序设计的目标是一系列通 过定义明确的接口通信来协同工作的类。耦合度反映了这些类联系的紧密度。我们努力要获得 低的耦合度,或者叫作松耦合(loose coupling)。

耦合度决定修改应用程序的容易程度。在一个紧耦合的结构中,对一个类的修改也会导致 对其他一些类的修改。这是要努力避免的,否则,一点小小的改变就可能使整个应用程序发生 改变。另外,要想找到所有需要修改的地方,并一一加以修改,却是一件既困难又费时的事情。 另一方面,在一个松耦合的系统中,常常可以修改一个类,但同时不会修改其他类,而且 整个程序还可以正常运作。

本周会讨论紧耦合和松耦合的例子。 聚合与程序中一个单独的单元所承担的任务的数量和种类相对应有关,它是针对类或方法 这样大小的程序单元而言的理想情况下,一个代码单元应该负责一个聚合的任务(也就是说,一个任务可以被看作是 一个逻辑单元)。一个方法应该实现一个逻辑操作,而一个类应该代表一定类型的实体。聚合 理论背后的要点是重用:如果一个方法或类是只负责一件定义明确的事情,那么就很有可能在 另外不同的上下文环境中使用。遵循这个理论的一个额外的好处是,当程序某部分的代码需要 改变时,在某个代码单元中很可能会找到所有需要改变的相关代码段。

增加可扩展性:

  • 可以运行的代码!=良好的代码
  • 对代码做维护的时候最能看出代码的质量

用封装来降低耦合

  • Room类和Game类都有大量代码和出口有关
  • 尤其是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();System.out.println("现在你在" + currentRoom);System.out.print("出口有:");showPrompt();}// 以下为用户命令private void printHelp() {System.out.print("迷路了吗?你可以做的命令有:go bye help");System.out.println("如:\tgo east");}//消除代码复制public void showPrompt() {System.out.println("你在" + currentRoom);System.out.print("出口有: ");System.out.print(currentRoom.getExitDesc());System.out.println();}private void goRoom(String direction) {Room nextRoom = currentRoom.getExit(direction);if (nextRoom == null) {System.out.println("那里没有门!");}else {currentRoom = nextRoom;showPrompt();}}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 {private String description;private Room northExit;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;}@Overridepublic String toString(){return description;}public String getExitDesc() {StringBuffer sb=new StringBuffer();if(northExit!=null)sb.append("north");if(eastExit!=null)sb.append("east");if(southExit!=null)sb.append("south");if(westExit!=null)sb.append("west");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("south")) {ret = southExit;}if(direction.equals("west")) {ret = westExit;}return ret;}}
}

转载原创文章请注明,转载自: Elton - 18.3.7 第5周 设计原则 5.1城堡游戏+5.2消除代码赋值+5.3封装(http://www.elton.site/?p=368)

18.3.7 第5周 设计原则 5.1城堡游戏+5.2消除代码赋值+5.3封装相关推荐

  1. 【设计模式】 面向对象六大设计原则

    面向对象设计的六大原则 : 单一职责原则, 里氏替换原则, 依赖倒置原则, 接口隔离原则, 迪米特法则, 开闭原则; 一. 单一职责原则 1. 单一职责简介 单一职责定义 : 有且只有一个原因引起类的 ...

  2. 十个面向对象设计原则

    追求高内聚highly cohesive 和松耦合 loosely couple 的解决方案是面向对象设计基本核心原则.这里列出OO设计中十大原则: 1. DRY (不要重复你自己) 这是指不写重复的 ...

  3. 设计原则与思想【面向对象、设计原则、编程规范、重构技巧】

    一.高质量代码的评判标准: 可维护性:在不破化原有代码设计.不引入新的bug的情况下,能够快速的修改或者添加代码 可读性:我们需要看代码是否符合编码规范.命名是否达意.注释是否详尽.函数是否长短合适. ...

  4. 设计原则——SOLID

    SOLID是5个设计原则的统称,它们分别是:单一职责原则.开闭原则.里式替换原则.接口隔离原则和依赖反转原则,依次对应SOLID中的S.O.L.I.D. 1.单一职责原则 单一职责原则,Single ...

  5. 必知必会的设计原则——迪米特原则

    概述 迪米特法则(Law of Demeter )又叫做最少知识原则,即一个对象应该对另一个对象有最少的了解. 迪米特法则的目的在于降低类之间的耦合.由于每个类尽量减少对其他类的依赖,因此,很容易使得 ...

  6. 第六周 Java语法总结_设计原则_工厂模式_单例模式_代理模式(静态代理_动态代理)_递归_IO流_网络编程(UDP_TCP)_反射_数据库

    文章目录 20.设计原则 1.工厂模式 2.单例模式 1)饿汉式 2)懒汉式 3.Runtime类 4.代理模式 1)静态代理 2)动态代理 动态代理模板 21.递归 22.IO流 1.File 2. ...

  7. 8.18 模块设计原则:高内聚低耦合

    8.18 模块设计原则:高内聚低耦合 模块内聚 定义(软考) 块内联系:模块内各元素的关联.交互程度 从功能角度:自己的功能自己实现,不麻烦其它模块 如何实现高内聚 功能内聚:模块的功能尽可能单一 模 ...

  8. 技术图文:01 面向对象设计原则

    01 面向对象设计原则 知识结构: 一碟开胃的小菜 小菜今年计算机专业大四了,学了不少软件开发方面的东西,也学着编了些小程序,踌躇满志,一心要找一个好单位.当投递了无数简历后,终于收到了一个单位的面试 ...

  9. 引导未来:区块链经济七大设计原则

    加拿大瑞尔森大学隐私与大数据研究所执行理事安·卡沃基安认为:"自由是创建在隐私之上的.我第一次认识到 这一点是在30年前,那时我刚开始参加在德国的各种会议.在隐私及数据保护方面,德国在全世界 ...

最新文章

  1. 上市之后,青云存储平台 QingStor 也要“进军”云原生
  2. 手把手教你学51单片机-c语言版期末考试,手把手从零教你学51单片机
  3. 我要认真学Git了 - Config
  4. 专研自动驾驶,深动科技春季招聘启动,含社招和实习
  5. iOS中UIKit继承结构
  6. 采用SHELL,通过SQL LOAD导入一定格式的txt文件至数据库中
  7. SpringSecurity系列(三) Spring Security 表单登录
  8. js和jquery给iframe src赋值的3种方法
  9. 变分法,欧拉-拉格朗日方程推导
  10. 云计算就业前景怎么样 学后可以胜任哪些岗位
  11. 安装nodejs遇到的坑
  12. 【机器视觉硬件】机器视觉硬件学习笔记2——工业相机
  13. CodeForces 581A Vasya the Hipster
  14. 国土导弹光学反狙击探测系统行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  15. 读美妆论文AN AUTOMATIC FRAMEWORK FOR EXAMPLE-BASED VIRTUAL MAKEUP
  16. webpack 打包错误
  17. FFT results in spectrum alising,picket fence effect, spectrum leakage, spectrum interference
  18. 使用PS批量处理图片大小
  19. Android手机投屏初探
  20. api是什么意思?又该如何使用呢?

热门文章

  1. 苏州市java岗位的薪资状况(1)
  2. 抖音自媒体上热门难不难?掌握这些技巧,你也可以上热门
  3. TS—枚举Enum用法
  4. 基SpringBoot的智能社区警务管理平台
  5. DataWriter和DataReader的Listener多种定义方式
  6. 09 基于STM32智能甲醛浓度检测超限报警系统设计
  7. FTP协议及其安全问题
  8. Python自制随机食物生成器(食物可自拟)
  9. 跨站请求伪造Cross-Site Request Forgery-CSRF
  10. execution 表达式用法汇总