从实验2开始,需要自己设计ADT,开始软件设计的第一步,在此写下这篇博客对实验2的相关问题进行总结
1.Java接口(Interface)的相关知识(P1)
首先看一个MIT给出的Interface的例子
public interface Graph<L> {
public static <L> Graph<L> empty() {
return new ConcreteEdgesGraph<L>();
}
public boolean add(L vertex);
public int set(L source, L target, int weight);
public boolean remove(L vertex);
public Set<L> vertices();
public Map<L, Integer> sources(L target);
public Map<L, Integer> targets(L source);
}
Java的接口是方法的集合,但是没有具体的实现。
需要使用接口的原因是因为Java不像C++支持多继承。
接口实现的语法需要用到implement
例如:
public class ConcreteEdgesGraph<L> implements Graph<L>{
}
本次实验可以通过一个接口,实现两种构建图的方式,这一点就体现了Java的Interface的功能
2.泛型编程知识总结(P1)
在本实验中,泛型编程比较简单,根据惯例,需要使用到< T >
< T >就是一个泛型
泛型的好处从最简单的编程角度就是避免了强制类型转换的麻烦。
从软件工程的角度来说,使ADT有了更强的可复用性,在后面的P2可以看出来泛型编程的好处和优越性
对于本次实验改为泛型的方法如下
对于原来的Edge和List< Edge >改为Edge< L > and List<Edge< L >>
像一些构造器new ConcreteEdgesGraph() or new Edge()改为 new ConcreteEdgesGraph< String >() and new Edge< L >().
3.复用知识浅谈 继承与委托(P1,P2)
实验1与实验2都有对写好的Graph ADT复用的问题
可以选择委托或者类继承,MIT在GraphPoet给出的是委托的方法
private final Graph<String> graph = Graph.empty();
在P2 FriendshipGraph中,可以选择继承,或者选择委派,相比继承而言,显然委派是一种更好的黑盒应用
在继承中,要考虑到Graph ADT的内部实现,而委托可以不考虑其内部实现从而直接使用Graph ADT的各种方法。可以更好的复用Graph中已经实现的代码,极大的降低了实现难度
4.简单应用(下棋)的设计(P3)
相比前两个应用已经给出了基本框架,P3需要从0开始,所以这就体现了设计的重要性,如果对于一个应用的基本框架没有设计的话,自然会导致代码逻辑非常混乱,甚至写到一半需要推倒重写。
建造高楼大厦都需要图纸,那么设计好框架就像设计图纸一样,我们要设计出UML图来完成这个棋类应用的图纸
4.1ADT框架设计
虽然代码还是一片空白,不过指导书已经给出了一些简单的类,那么就需要梳理一下指导书给出的几个类之间的关系,这也是P3的重中之重。
实验指导书给出以下几个类
Game,Action,Board,Player,Position,Piece
设计方案其实是多种多样的,所以在此只谈我本人的一种设计思路,不敢说是最好的实现,不过相对来讲还是比较好实现的
Game类显然是最顶层的类,需要其他几个类来共同实现这个类,还是比较好理解的。
不过接下来的类的设计就比较复杂了
首先来看Board,对于棋盘,棋盘上有许多可以放置棋子的位置,而且上面也会有棋子,那么我们不妨将棋盘抽象为棋子与位置之间的映射,这样
Piece和Position与Board的关系就非常明显了
对于Action类,其实对于围棋和象棋,两位玩家共享一个棋盘,也就是棋盘是个public的,那么无论哪一方进行action,改变的一定是board,这样Board类和Action类之间的关系也建立了起来
对于Player类其实可以把它完全剥离出去,可能有人会觉得Action依赖于Player,不过这样就把问题想复杂了,因为无论是谁的Action,最终结果都显现在棋盘上,所以Player类其实非常简单
并且Spec有要求要记录两边下棋的历史,所以把Action toString之后加入到PlayerHistory之后即可
4.2 人机交互与客户端
这里不得不说,虽然这门课叫软件构造,不过在做实验的时候,人机交互与客户端的知识教的比较少,而且关于GUI的许多知识很多人也没有系统学过,在这里我想浅谈一下人机交互,和这次我采用的命令行程序的一些感受
本人在大一小学期学过一些.NET架构的WinForm与Web应用设计
对于WinForm的程序设计,.NET架构的设计非常简单,已经基本实现了懒人编程,即只需要编程用户点击某个模块之后的行为即可。
对于Web的程序设计是比较复杂的,因为设计到了不少前端的东西,整个界面的UI需要用到HTML语言,比单纯的WinForm要复杂不少
说的有点远,说回到这一次的人机交互设计,其实和.NET设计中有异曲同工之妙,例如.NET中用户对于所有模块的所有行为都要给出逻辑支撑,不能出现逻辑冲突,或者执行结果不正确的情况
在本次设计的主程序中,我们也要保证,用户的输入要给出完整且正确的反馈,输入的坐标行为必须给出正确处理
同时,也要做到让用户懒人使用,因为软件终究要面向客户,大部分客户只会用极少的操作去实现很复杂的操作,总不能期望你的客户写一个脚本执行你的应用,这次的设计中,我选择让客户用菜单选择的方法来简化用户的操作,用非常简单的Switch Case语句实现
5.总结
软件构造其实很多技术是非常简单的,但是能否设计好整体的框架,定好最初的基调,让用户用的爽,这是需要大量的经验积累出来的,所以还是要多想多练