0

我写了一个这样的示例代码:

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 构造函数中看到的那样,它接受任何“是”BaseClass 的对象并另外持有对它的引用,所以也许我应该立即让图表看起来像这样:

    ______|>BaseClass<|_______
   |             |            |
ClassA           |________<>ClassB

哪一个更合适,或者为什么它们都不合适,正确的图表会是什么样子?

任何关于它的想法和推理都将受到欢迎。谢谢

编辑:事情是 ClassB 继承自 BaseClass,但它也持有对 BaseClass 派生对象的引用并使用该对象。所以简而言之,我的问题是:如何在类图上描述它?

4

2 回答 2

0

在 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           |.
.........+-------------------------------------------------+.
.............................................................

干杯。

于 2012-06-28T15:55:21.147 回答
0

第二张图是对的。第一个只是第二个可能的“实例”。

于 2012-06-28T14:55:40.897 回答