本节书摘来自异步社区《UML面向对象设计基础》一书中的第1章1.12节答案作者【美】Meliir Page-Jones更多章节内容可以访问云栖社区“异步社区”公众号查看。
1.12 答案UML面向对象设计基础①a 有两个建议一是假设START方块完全被墙包围二是假设某人在方格中忘记标记FINISH方块。修改算法处理这两种情况以及其他任何你考虑到的异常情况如没有对advanceOK是否为真安全检查。
b该操作中的问题是Grid对象中的insertHominoid操作需要locationSquare (Hominoid对象的开始位置)的信息吗 应该使用该信息告诉Homoid对象它的初始位置但Homoid没有定义setLocation操作因此不应在Grid中定义insertHominoid操作而应在Homoid中定义insertIntoGrid(gridGridlocationSquareout insetOKBoolean)操作。此外还需要在Grid中定义isAWallLocationBoolean操作。
② 回答是肯定的。对象有一个不必声明的变量实际上是常量保存自己的句柄。该变量由关键字selfthisthis 或Current分别对应SmalltalkCJava或Eiffel来命名。
③ 因为这样做会使消息的目标改变了其中一个参数的句柄这是一种拙劣的设计方法。消息的发送者有权保证其变量的句柄在发送消息的前后保持一致。少数语言禁止这种方法在其手册中有这样的说明“参数通过传送值进行对象访问且不能被目标操作代码改变。”
④ 在彻底的面向对象语言如Smalltalk中所有一切的都是对象实际上Smalltalk坚决地进行“不含数据”的定位。例如在Smalltalk中下面的加法表达式
x <- 5 7 解释为“向参数对象5和对象7发送消息plus。”赋值操作符<-解释为“用变量x替换对象12的句柄。”然而并不是所有面向对象语言都像Smalltalk那样严格。在类似Eiffel的语言中仍然有数据类型如integerrealcharBoolean等。但任何主要的结构在运行时是创建对象实例而不是数据实例的类。由于编程原因Eiffel妥协了“所有都是对象”的原则将整数、字符等作为可以与C代码接口兼容的数据类型。在C中具有标准数据类型的标准C程序可以与C程序混合使用。因此在C中所有顾虑可以打消但当我告诉人们纯面向对象中没有数据时经常受到人们的抨击。最普通的例子是人们用Integer和Date反对我。为什么这些是类而不是传统的数据类型在使用数字5之前是否必须先声明Integer.New而在使用1066年9月25日之前是否必须先声明Date.New ?回答是否定的。诸如Integer或Date这样的类被称为文字类literal classes。属于文字类的对象称为文字对象literal objects。文字对象就是其表示的值。大多数文字对象是不变的从不改变值。尽管每种面向对象语言都有其处理文字类的方式但多数语言假设文字类的所有实例是预先定义的或在原处通过转换类似“3月15日”的文本串创建的。在将这种“类”作为标准数据类型的语言中实例实际上是传统的数据值而不是对象。在下面两种情况下从文字类进行实例化是不必要的也是非法的
JavascriptInteger.New // 非法代码
Date.New // 在大多数语言中是非法代码
⑤ 困难在于类要知道“哪个对象的属性”。回忆一下对于一个给定类在运行时可能会有上千个对象。想要获取该类的某个对象的唯一方法是知道该对象的句柄然后发送消息给它。尔后该对象友好地将属性消息返回给发送消息的类。⑥ 创建了一个对象每当执行类操作New时总是创建一个带有句柄的对象。然而这个程序中命名为gl的对象是Glider的实例通过继承它也是Aircraft的实例。⑦ 面向对象程序的初始化依赖于你所使用的语言和操作系统。操作系统可以通过三种普通的方式将控制转移给应用程序从主函数开始执行与常规的过程语言一样在程序启动时获得控制。自动示例一个程序员定义的类Root的对象从其实例开始整个程序的执行。生成一个面向对象浏览环境通常具有图形界面。然后用户/程序员可以交互式地向适当的类或对象发送消息使程序运行。⑧ 当关掉计算机时丢失了内存中的所有对象及其所包含的信息。如果这样对你有影响则必须在面向对象程序终止前将信息保存在磁盘上。在面向对象数据库管理系统ODBMS中多少可以直接存储对象。但如果你使用的是关系型数据库就不得不在存储信息之前将对象信息“分解”成通常的表格形式。⑨ 当关掉计算机时对类没有什么影响对大多数环境而言。你的类已经编译并保存在永久的磁盘上。这也说明了类和对象之间的区别前者是永久的形式而后者是易变的运行单元。⑩ 在一些语言中不守规矩的设计者可以设计一些方法使外界可以“跳过对象的围墙”并直接处理变量。一种方法是通过C的“友元”方法。与多数其他设计过失一样这种方法通常具有影响大的罪名。11.tif 如果你已经为你目前所使用的语言选择了一种术语考察一下哪个面向对象属性你认为最有价值。如果你选用的语言不是完全面向对象的你最希望你的语言应具有本章提到的哪些特性为什么12.tif Java实际上只支持本章描述的“继承能力”意义上的单继承。假设类S有下面的语句extends C implements I1I2表示S可以访问C的所有操作Java方法。换言之通过extends的构造S不仅继承了C的接口而且还继承了C的能力使接口工作的代码。然而通过implements 构造S继承了责任但没有继承能力。在这个例子中S的设计者或程序员对于定义在接口I1和I2中所有操作负责提供可行的Java方法。13.tif 下面是你可能用Java重写的机器人程序。假设该算法包含在操作navigate中它将是类Grid的一个操作对方格对象的任何访问都通过this。还假设方格对象被正确地初始化如以前插入的任何机器人已被删除。
Public boolean navigate( )
{// 在起始方格中放入一个新机器人并将机器人导航到正确的结束方格每一步都显示机器人。如果算法有问题则返回false否则返回true。
Hominoid hom new Hominoid ( )// 创建Hominoid的新实例由hom表示
int oneSquare 1 // 常量
int initialTurnCount
Square startSquare this.start
Boolean insertOK this.insertHominoid(homstartSquare)
//如果成功insertHominoid返回true
if (!insertOK) return false
//如果机器人没有将OK放入方格中则终止。
// 将机器人设置为正确的方向
// 将机器人最多转4次或直到机器人在其前方有清楚的路径
initialTurnCount 1
while (initialTurnCount < 4 initialTurnCount}
// endwhile结束
this.display() //显示方格
hom.display() //显示机器人
while (hom.location ! this.finish)
{ if (hom.facingWall)
{hom.turnLeft()
if(hom.facingWall) { hom.turnRight()hom.turnRight()}
// endif结束
} // endif结束
hom.advance(oneSquare)
hom.display
} // endwhile结束
//机器人成功结束!
return true
} //结束导航
本文仅用于学习和交流目的不代表异步社区观点。非商业转载请注明作译者、出处并保留本文的原始链接。【文章原创作者:香港服务器 http://www.558idc.com/hk.html提供,感谢支持】