我写了一个这样的示例代码:
class BaseClass
{
public virtual void Execute() {}
}
class ClassA: BaseClass
{
public override void Execute()
{
// ClassA Execute implementation
}
}
class ClassB: BaseClass
{
private BaseClass _b;
public ClassB(BaseClass b)
{
_b = b;
}
public override void Execute()
{
_b.Execute();
}
}
...
ClassB b = new ClassB(new ClassA());
我想为上面的代码绘制一个合适的 UML 图:
<|_______ = inheritance = "is-a"
<________ = association
<>_______ = aggregation = "has-a"
因为 ClassB 实际上使用 ClassA,所以我的图表看起来像这样:
______|>BaseClass<|_______
| |
ClassA<_____________________ClassB
但是正如我们从 ClassB 构造函数中看到的那样,它接受任何"is-a"BaseClass 的对象,并且还包含对它的引用,所以也许我应该立即使图看起来像这样:
______|>BaseClass<|_______
| | |
ClassA |________<>ClassB
哪一个更合适,或者为什么它们都不合适,正确的图表会是什么样子?
欢迎对此提出任何想法和推理。谢谢
编辑:问题是 ClassB 继承自 BaseClass,但它也包含对 BaseClass 派生对象的引用并使用该对象。所以简而言之,我的问题是:如何在类图上描绘它?
第二个图是正确的。第一个只是第二个的可能"实例"。
在U.M.L.之前,我曾经使用过一些方法,这些方法具有独立的继承和组合图。在 U.M.L. 中,我仍然将两个图表分开,至少有一个非常充分的理由将它们混合在一起。
我建议也这样做。
例。
让我们假设我正在使用一种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 |.
.........+-------------------------------------------------+.
.............................................................
干杯。