回顾回顾UML类图的画法,争取自己画出的图能让其他人看得懂。
我为什么要借助红色警戒这个游戏来说明UML类图的画法呢,因为我觉得大家都玩过,对他们的内容都有一个清晰的认识,其次是不想让我的文章太晦涩难懂毫无生机,所以我们就来搞点事情吧~
本期博客我们邀请到的嘉宾有:
![]() | 姓名:动员兵 类名:unit.soldiers.Conscript 单位代码:1004 |
![]() | 姓名:美国大兵 类名:unit.soldiers.AmericanSoldiers 单位代码:1001 |
![]() | 姓名:工程师 类名:unit.soldiers.Engineer 单位代码:1002 |
![]() | 姓名:谭雅 类名:unit.soldiers.Tanya 单位代码:1003 |
![]() | 姓名:犀牛坦克 类名:unit.vehicle.Tank 单位代码:2001 |
![]() | 姓名:多功能步兵车 类名:unit.vehicle.Conscript 单位代码:2002 |
![]() | 姓名:天启坦克 类名:unit.vehicle.Conscript 单位代码:2003 |
![]() | 姓名:兵营 类名:unit.architecture.Barracks 单位代码:3001 |
![]() | 姓名:战车工厂 类名:unit.architecture.VehicleFactory 单位代码:3002 |
![]() | 姓名:发电厂 类名:unit.architecture.PowerPlant 单位代码:3003 |
首先:我们介绍一下包结构
![]() | 总包是util包,也就是定义了各种单位。 utils下分为四大类包: 1、建筑包architecture 2、公共包common 3、士兵单位包soldiers 4、战车包vehicle 每个包下面都有各自的类 建筑包下: 1、抽象建筑类,定义了必须的方法 2、兵营Barracks 3、电厂PowerPlant 4、战车工厂VehicleFactory 公共包下: 1、Weapon包(定义各种武器类) IWeapon为武器接口 2、全局单位编码常量类 3、全局单位数据库 士兵包下: 1、抽象士兵类 2、美国大兵类 3、苏联动员兵类 4、工程师类 5、谭雅类 战车包下: 1、抽象战车类 2、天启坦克类 3、多功能步兵车类 4、犀牛坦克类 |
1、UML类表示法
以美国大兵为例,我们希望他拥有
+ 表示public,- 表示private,# 表示protected ,:表示类型 所以对应的Idea生成的uml图如中间所示 标准的uml图如右侧所示。 相比之下还是IDEA自动生成的比较好看 | ![]() | ![]() |
由此我们设计出美国大兵的类代码,这只是一个为了说明UML关系画法的代码,杠精们别高潮:
package unit.soldiers;
import unit.common.weapon.MachineGun;
import java.util.ArrayList;
import java.util.List;
/**
* @program: unit.soldiers
* @description:
* @author: liujinghui
* @create: 2019-03-30 10:56
**/
public class AmericanSoldiers{
private int hp;
private int speed;
private int rank;
private int country;
private static final List<MachineGun> weapons = new ArrayList<MachineGun>(){
{
add(new MachineGun());
}
};
public void report() {
System.out.println("Sir!Yes Sir!");
}
public int attack() {
int damage = 0;
for(MachineGun machineGun : weapons){
damage += machineGun.fire();
}
return damage;
}
protected void sitdown(){
}
}
2、UML类继承关系表示法
红警中有各种各样的士兵,他们都会有一些共用的方法,这个时候我们会做一下抽象。
例如将所有士兵的说话report和攻击attack的方法做成抽象的,这个时候我们就可以提取抽象类AbstractSoldiers
我们把美国大兵,动员兵,谭雅,工程师都提出了两个公共方法(工程师怎么攻击??大概是用扳手砸吧)
此时,继承关系使用的是实线加三角形箭头的方式表示,可以记忆成:所有的人都指向了他们的公共技能类,所以他们就都得到了这些公共的技能。
在VISIO中,继承关系是使用实线加空心三角形箭头,并且抽象类抽象方法要斜体表示
3、UML接口实现关系表示法
红警中各种单位都配备有武器,武器都有一个功能,那就是开火。因此我们可以对武器进行抽象,提取一个公共的接口那就是开火fire();
首先我们定义一些武器类:手枪、机枪、120mm炮、150mm炮等。他们都有一个属性那就是伤害。
设计出来的类图就是如下所示:
代码示例
public class Cannon120MM implements IWeapon{
private static final int damage = 1200;
@Override
public int fire() {
return damage;
}
}
可以看到IDEA生成的类图中,实现接口使用的是:三角形箭头+虚线
正常的VISIO中继承实现是:空心三角形箭头+虚线
4、UML类组合关系表示法
上面的内容其实都很简单,不过不知道大家有没有注意过,如果IFV(多功能步兵战车)和导弹武器其实是组合在一起的,所以这个时候IFV就会组合机枪这个武器了。
所以我们画出组合的关系图:
可以看出依赖关系是实线加实心菱形组成,注意不是三角形。其实反映在一个类中,它的成员变量包含了另一个类,也就是一个类需要由其他的类共同组成。菱形指向被组合的对象(IFV),数字表示组合的数量。
VISIO中也是如此表示,没有差异。
由此我们编写代码,并且大家可以参考红框中的内容。
5、UML类依赖关系表示法
也许有人会发现这里除了实心菱形还有虚线的箭头,这表示类中的依赖关系,具体是哪里的依赖呢,其实就是attack方法需要依赖武器。依旧来看上面的代码,这里依赖了MissileBox去实现一些功能。
所以:依赖所指的就是方法中对其他类的依赖,包括方法体和参数
VISIO中UML类图也是如此表示,没有差异!
6、UML类聚合关系表示法
一些游戏都会有集群效果,比如绝命时刻的中国坦克,当一定数量的坦克聚集在一起就会组成一个集群,集群包含了n多个实体
Idea中表示方法跟Visio中不太一样:正常的聚合关系是空心菱形+直线
他跟组合关系的区别:聚合关系表示集群里的个体的生命周期和集群类可以不一样,但是组合关系必须是相同的生命周期。
![]() | ![]() |
以上就是个人对UML的一些理解。