模块化C代码与UML对象模型之间的映射(3)——UML关系
2011-08-17 21:16
615 查看
下图是从StarUML工具界面截下来的,从上往下依次表示UML的关系:关联、单向关联、聚合、组合、泛化、依赖和实现。
图3 UML关系集
聚合的整体不负责部分的生命期,组合的整体负责部分的生命期。关联关系需根据实际场景来识别,例如军队和士兵的关系一般可理解为聚合,士兵退役了就和军队脱离聚合关系了。但是,如果是打仗时,士兵们必须生死与共,军队没了则士兵命也没了,则可理解为组合。
UML示例:
图3-1 关联、聚合、组合
C代码示例:
下面举一个用C语言实现继承的一个经典例子,从Linux内核源码中拷贝过来的。
UML示例:
图3-2 继承(泛化)
C代码示例(删节版):
注意:继承不是定义结构体指针,而是定义结构体。
UML示例:
由于类的客户要依靠接口实现类的操作,所以我们把与接口的交互建模为一种依赖关系。
图 3-3 依赖
C代码示例:
下面再拿Linux设备驱动做例子。scullc_dev类实现文件操作接口file_operations。
UML示例:
图3-4 实现
C代码示例:
图3 UML关系集
3.1 关联、聚合、组合
关联(association)是一种结构关系,它指明一个事物的对象与另一个事物的对象间的联系。聚合和组合是更强的关联,表示整体和部分的关系。聚合的整体不负责部分的生命期,组合的整体负责部分的生命期。关联关系需根据实际场景来识别,例如军队和士兵的关系一般可理解为聚合,士兵退役了就和军队脱离聚合关系了。但是,如果是打仗时,士兵们必须生死与共,军队没了则士兵命也没了,则可理解为组合。
UML示例:
图3-1 关联、聚合、组合
C代码示例:
//A关联/聚合/组合了B struct A{ struct B *b; void (*Create)(B *b); //方式1 }; struct A{ struct B *b; void (*SetB)( B *b); //方式2,单B }; struct A{ struct B *bset ; void (*RegisterB)(B *b); //方式3,B集 };
3.3 泛化
泛化(generalization)是一种特殊/一般的关系。也可以看作是常说的继承关系。下面举一个用C语言实现继承的一个经典例子,从Linux内核源码中拷贝过来的。
UML示例:
图3-2 继承(泛化)
C代码示例(删节版):
struct kobject { const char *name; struct kobject *parent; }; struct cdev { struct kobject kobj; //继承kobject const struct file_operations *ops; dev_t dev; unsigned int count; }; struct scullc_dev { void **data; struct scullc_dev *next; struct cdev cdev; //继承cdev };
注意:继承不是定义结构体指针,而是定义结构体。
3.2 依赖
依赖(dependency)是两个事物之间的语义关系,其中一个事物(独立事物)发生变化,会影响到另一个事物(依赖事物)的语义。最常用的依赖关系是一个类的构造函数中用到另一个类的定义。UML示例:
由于类的客户要依靠接口实现类的操作,所以我们把与接口的交互建模为一种依赖关系。
图 3-3 依赖
C代码示例:
//方式1 void A_Method(struct A *a) { B_Method(); //B是实用类(即全局的实例),这种依赖方式在我们系统中最最多 } //方式2 void A_Method(struct A *a, const struct B *b); //B作为参数被传递 //方式3 void A_Method(struct A *a) { struct B *b = B_Create(); //B在A的方法中实例化 }
3.4 实现
实现(realization)是类元之间的语义关系,其中的一个类元指定了由另一个类元保证执行的契约。下面再拿Linux设备驱动做例子。scullc_dev类实现文件操作接口file_operations。
UML示例:
图3-4 实现
C代码示例:
//实现接口函数 int scullc_open (struct inode *inode, struct file *filp) { struct scullc_dev *dev; /* device information */ /* Find the device */ dev = container_of(inode->i_cdev, struct scullc_dev, cdev); /* ...*/ /* and use filp->private_data to point to the device data */ filp->private_data = dev; return 0; /* success */ } ssize_t scullc_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { struct scullc_dev *dev = filp->private_data; /* the first listitem */ struct scullc_dev *dptr; int quantum = dev->quantum; /* ... */ return retval; } //… //文件操作接口实例 struct file_operations scullc_fops = { .owner = THIS_MODULE, .llseek = scullc_llseek, .read = scullc_read, .write = scullc_write, .ioctl = scullc_ioctl, .open = scullc_open, .release = scullc_release, }; // static void scullc_setup_cdev(struct scullc_dev *dev, int index) { int err, devno = MKDEV(scullc_major, index); cdev_init(&dev->cdev, &scullc_fops); //注册接口 dev->cdev.owner = THIS_MODULE; dev->cdev.ops = &scullc_fops; err = cdev_add (&dev->cdev, devno, 1); /* Fail gracefully if need be */ if (err) printk(KERN_NOTICE "Error %d adding scull%d", err, index); }
相关文章推荐
- 模块化C代码与UML对象模型之间的映射(3)——UML关系
- 模块化C代码与UML对象模型之间的映射(1)——类、单例类及实用类
- 模块化C代码与UML对象模型之间的映射(2)——抽象类与继承
- 模块化C代码与UML对象模型之间的映射(4)——常见问题小结
- 模块化C代码与UML对象模型之间的映射(4)——常见问题小结
- 模块化C代码与UML对象模型之间的映射(2)——抽象类与继承
- 模块化C代码与UML对象模型之间的映射(1)——类、单例类及实用类
- 浅谈UML中类之间的五种关系及其在代码中的表现形式
- 【BACnet】3.bacnet-stack-0.8.0工程与BACnet标准协议之间的代码关系(对象及应用服务)
- mybatis对象之间映射关系以及数据库表建立的时候外键的添加
- 对象-关系数据库之间的映射
- UML图形 X 类之间的关系 X 实现代码
- Hibernate映射对象之间的多种关系
- 对象-关系数据库之间的映射
- UML描述对象和类之间的相互关系
- Hibernate笔记2--映射对象之间的关系
- mybatis对象之间映射关系以及数据库表建立的时候外键的添加
- mybatis对象之间映射关系以及数据库表建立的时候外键的添加
- Json格式与对象之间的映射关系
- [原创]Object/DataSet Relational Mapping(对象/数据集关系映射)补充代码1