Java应用程序由许多类所构成,是Java实现面向对象应用程序的核心。类图主要描述Java应用程序中各种类之间的相互静态关系,如类的继承、抽象、接口以及各种关联。要利用UML设计Java应用程序,仅仅使用类图来描述这些静态关系,利用可视化工具,要实现Java应用程序的代码自动生成,是远远不够的。我们还必须描述各种类相互之间的协作关系、动态关系,如时间序列上的交互行为。其中UML序列图就是用来描述类与类之间的方法调用过程(或消息发送)是如何实现的。
本文通过一个具体的应用程序的设计与实现过程,详细说明了利用UML序列图设计Java应用程序,使得开发过程标准化、可视化,代码编程简单化。
我们要设计的应用程序FlooringClient是用来计算在一定面积的表面上贴上规格化的地板砖或墙纸所需要的地板砖或墙纸材料的长度和价钱。该程序涉及到三个类:FlooringClient、Surface以及Floor。其各自的类图以及程序代码分别如下
/*
* FlooringClient.java
*
*/
class FlooringClient {
public static void main(String[] args){
Surface theSurface=new Surface("Margarets Floor",5,6);
Flooring theFlooring=new Flooring("Fitted carpet",24.50,5);
double noOfMeters=theFlooring.getNoOfMeters(theSurface);
double price=theFlooring.getTotalPrice(theSurface);
System.out.println("You need "+noOfMeters+" meters,price$ "+price);
}
}
/*
* Surface.java
*
*/
class Surface {
private String name; // for identification purposes
private double length;
private double width;
public Surface(String initName, double initLength, double initWidth) {
name = initName;
length = initLength;
width = initWidth;
}
public String getName() {
return name;
}
public double getLength() {
return length;
}
public double getWidth() {
return width;
}
public double getArea() {
return width * length;
}
public double getCircumference() {
return 2 * (length + width);
}
}
/*
* Flooring.java
*
*/
class Flooring {
private static final double limit = 0.02; // limit for one more width
private String name; // for identification purposes
private double price; // price per meter
private double widthOfFlooring; // meter
public Flooring(String initName, double initPrice, double initWidth) {
name = initName;
price = initPrice;
widthOfFlooring = initWidth;
}
public String getName() {
return name;
}
public double getPricePerM() {
return price;
}
public double getWidth() {
return widthOfFlooring;
}
/*
* We are going to calculate the amount which is needed to cover one surface.
* The flooring is always placed crosswise relative to the length of the surface.
* If you want to find the amount the other way, you have to change
* width and length in the surface argument.
*/
public double getNoOfMeters(Surface aSurface) {
double lengthSurface = aSurface.getLength();
double widthSurface = aSurface.getWidth();
int noOfWidths = (int)(lengthSurface / widthOfFlooring);
double rest = lengthSurface % widthOfFlooring;
if (rest >= limit) noOfWidths++;
return noOfWidths * widthSurface;
}
public double getTotalPrice(Surface aSurface) {
return getNoOfMeters(aSurface) * price;
}
}
以上三个类之间的类图关系可以表示为如下图:
以下我们来详细分析类FlooringClient是如何发送消息给其它类,而实现方法的调用过程。并如何用UML序列图来描述这一序列过程。
一、getNoOfMeters()方法
让我们来看看是如何发送消息getNoOfMeters()的。对象Flooring要计算出需要多少米的材料才能贴满一定面积的表面,就需要对象Flooring与对象Surface之间相互作用。
FlooringClient通过发送消息给getNoOfMeters()对象Flooring,在getNoOfMeters()方法的代码中,Flooring又发送消息给Surface而得到length和width。
以上过程用UML序列图描述如下图:
UML序列图描述了消息是如何在给对象间发送的。下面我们来详细解释以上UML序列图的含义,通过上述序列图,我们得知有以下8个过程:
1. FlooringClient新建一个对象theSurface
2. FlooringClient新建一个对象theFlooring
3. FlooringClient发送一个消息给对象theFlooring,并以theSurface为变量
4. theFlooring发送一个消息getLength()给theSurface
5. theSurface发送一个回应给theFlooring
6. theFlooring发送一个消息getWidth ()给theSurface
7. theSurface发送一个回应给theFlooring
8. theFlooring发送一个回应给FlooringClient
二、getTotalPrice()方法
在FlooringClient程序中,我们有如下语句:
double price=theFlooring.getTotalPrice(theSurface);
getTotalPrice()方法为:
public double getTotalPrice(Surface aSurface) {
return getNoOfMeters(aSurface) * price;
}
该过程用UML序列图描述如下图
三、同一个类的两个对象之间的交互
一个对象可以与同一个类的另一个对象交互从而完成程序所规定的任务。如果我们在Surface类中增加一个比较面积的方法。程序代码为:
public int compareAreas(Surface theOtherSurface){
final double precision=0.00001;
double area1=getArea();
double area2=theOtherSurface.getArea();
if (Math.abs(area2-area1)
else if(area1>area2) return ?1;
else return 1;
}
在主程序FlooringClient中,我们可以实现如下代码
Surface surface1=new Surface("A",5,4);
Surface surface2=new Surface("B",4,4);
Int result=surface1.compareAreas(surface2);
If (result<0) System.out.println(surface1.getName()+"is the smaller one");
else If (result>0) System.out.println(surface2.getName()+"is the smaller one");
else System.out.println("The surface has the same area");
从以上程序中可以看出,surface1与surface2发生交互从而得到结果result。首先它计算出自己的面积,然后计算出surface2的面积,最后再比较它们两个之间的面积的大小。
以上过程用UML序列图可以描述为下图:
以上详细说明了如何利用UML序列图来描述各类之间的对象或同一类不同之间的对象相互之间的交互序列过程。是Java应用程序面向对象设计过程中的一个重要方面。