在 UML 之前,我曾经使用过一些方法,它们具有独立的继承和组合图。我仍然在 UML 中将这两个图分开,除非有充分的理由将它们混合在一起。
我建议也这样做。
例子。
假设我正在使用一种类似 C++ 的编程语言,它不支持多重继承,但支持单一继承。
假设我在一个面向对象和类的库中工作,并且我想使用类图、继承和其他关联对该库中使用的类进行建模。
假设我用“流”类制作了我的自定义输入/输出库。
首先,我创建了一个基本的“流”类:
............................................................
.+--------------------------------------------------------+.
.| <<abstract>> |.
.| StreamClass |.
.+--------------------------------------------------------+.
.| [+] bool canRead() <<virtual>> |.
.| [+] bool canWrite() <<virtual>> |.
.| [+] bool canSeek() <<virtual>> |.
.| [+] bool isOpen() <<virtual>> |.
.| [+] void read(byte[] Buffer, int MaxSize) <<virtual>> |.
.| [+] void write(byte[] Buffer, int MaxSize) <<virtual>> |.
.| [+] void open() <<virtual>> |.
.| [+] void close() <<virtual>> |.
.+--------------------------------------------------------+.
............................................................
已经有一个文件系统库,我想用我的库“包装”,所以我想创建一个只读流和一个只写流类。
............................................................
.+--------------------------------------------------------+.
.| <<abstract>> |.
.| StreamClass |.
.+--------------------------------------------------------+.
.| [+] bool canRead() <<virtual>> |.
.| [+] bool canWrite() <<virtual>> |.
.| [+] bool canSeek() <<virtual>> |.
.| [+] bool isOpen() <<virtual>> |.
.| [+] void read(byte[] Buffer, int MaxSize) <<virtual>> |.
.| [+] void write(byte[] Buffer, int MaxSize) <<virtual>> |.
.| [+] void open() <<virtual>> |.
.| [+] void close() <<virtual>> |.
.+-+------------------------------------------------------+.
...^.........................................................
../.\........................................................
./...\........................................................
.--+--..........................................................
...|............................................................
...|...+---------------------------------------------------------+.
...|...| <<concrete>> |.
...|...| ReaderStreamClass |.
...|...+---------------------------------------------------------+.
...|...| [+] bool canRead() <<override>> |.
...+---+ [+] bool isOpen() <<override>> |.
...|...| [+] void read(byte[] Buffer, int MaxSize) <<override>> |.
...|...| [+] void open() <<override>> |.
...|...| [+] void close() <<override>> |.
...|...+---------------------------------------------------------+.
...|...............................................................
...|...+---------------------------------------------------------+.
...|...| <<concrete>> |.
...|...| WriterStreamClass |.
...|...+---------------------------------------------------------+.
...|...| [+] bool canWrite() <<override>> |.
...+---+ [+] bool isOpen() <<override>> |.
.......| [+] void write(byte[] Buffer, int MaxSize) <<override>> |.
.......| [+] void open() <<override>> |.
.......| [+] void close() <<override>> |.
.......+---------------------------------------------------------+.
...................................................................
到目前为止,我已经建模了一个基类,加上 2 个子类,没什么大不了的。
后来,我需要一个允许读写的类,但不能同时允许,所以,我决定使用组合,并创建一个新类,它是我的流基类的后代,但是,必须复合读写器类,可能是隐藏的。
我自己,或者其他将要使用这个类的程序员,不知道也不关心内部有其他流。
(1) 继承图:
............................................................
.+--------------------------------------------------------+.
.| <<abstract>> |.
.| StreamClass |.
.+--------------------------------------------------------+.
............................^...................
.........................../.\..................
........................../...\.................
..........................--+--.................
............................|...................
............................|...................
............................|................................
.+--------------------------+------------------------------+.
.| <<abstract>> |.
.| ReaderWriterStreamClass |.
.+---------------------------------------------------------+.
.| [#] ReaderStreamClass Reader() |.
.| [#] WriterStreamClass Writer() |.
.+---------------------------------------------------------+.
.| [+] bool canRead() <<override>> |.
.| [+] bool canWrite() <<override>> |.
.| [+] bool canSeek() <<override>> |.
.| [+] bool isOpen() <<override>> |.
.| [+] void read(byte[] Buffer, int MaxSize) <<override>> |.
.| [+] void write(byte[] Buffer, int MaxSize) <<override>> |.
.| [+] void open() <<override>> |.
.| [+] void close() <<override>> |.
.+---------------------------------------------------------+.
............................................................
(2) 组成图:
.............................................................
.........+-------------------------------------------------+.
.........| <<abstract>> |.
.........| ReaderWriterStreamClass |.
.........+-------------------------------------------------+.
..+------+ [#] WriterStreamClass Writer() |.
..|..+---+ [#] ReaderStreamClass Reader() |.
..|..|...+-------------------------------------------------+.
..|..|.......................................................
..|..|...+-------------------------------------------------+.
..|..+---+ <<concrete>> |.
..|......| ReaderStreamClass |.
..|......+-------------------------------------------------+.
..|..........................................................
..|......+-------------------------------------------------+.
..+------+ <<concrete>> |.
.........| WriterStreamClass |.
.........+-------------------------------------------------+.
.............................................................
干杯。