微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在UML对象和序列图中为同一对象分别显示引用类型和对象类型

如何解决如何在UML对象和序列图中为同一对象分别显示引用类型和对象类型

enter image description here

该图显示了示例类图以及序列图中这些类的对象的用法

在上图中,实例 myCar 可以通过 ShowroomItem 的引用或接口 Vehicle 的引用来引用。因此,客户驱动程序/销售工程师将获得功能访问权限。

我同意在实现阶段(例如 Java),这里不需要类型标识,我们将 myCar 视为自己使用的基类型(任一接口)的实例。

但是在序列图中,(为了清楚起见)我无法指出 myCarDriver 的引用应该是 VehicleSalesEngineer 应该是 ShowroomItem

我在 UML 2.0 书籍中搜索,我没有得到合适的符号。根据目前的理解,我可以将其显示"myCar : Vehicle""myCar : ShowroomItem",但这并不表示它的汽车对象称为接口.这个缺点并不强制 playMusic 在被称为 Vehcile 时不能工作。

有什么符号可以显示这种细节吗?

由于我对所提供的任何答案都不满意,我尝试添加以下内容以使问题更清楚,解决答案中提出的一些反对意见,并提出一种解决方案供专家审查。

评论,我觉得要么人们没有得到核心问题,要么我没有突出核心问题。首先让我演示代码不会破坏。以下代码允许 SalesEngineer 使用 sell() 和 buy() 功能访问 Abstraction,而 Driver 仅使用 start() 和 stop() 功能访问 Abstraction [以这种方式设计]。这是将不同抽象发布到不同客户端的接口的最强大功能。 Java 集合使用相同的多个基本类型,即 TreeSet 中的 ObjectComparable一个用于 equals(),另一个用于实体上的 compare()。

package com.se.stackoverflow;

interface Vehicle {
    abstract void start();
    abstract void stop();
}

interface ShowroomItem {
    abstract void buy();
    abstract void sell();
}

class Car implements ShowroomItem,Vehicle {
    // **Car IS-A Vehicle and ShowroomItem BY-DEFinitioN**
    // **and as per SOLID principle interface segregation**

    public void start() { System.out.println("Started");}
    public void stop() { System.out.println("Stopped");}
    public void sell() { System.out.println("Sold");}
    public void buy() { System.out.println("Baught");}
}

class SalesEngineer {
    private ShowroomItem item = null;
    public SalesEngineer(ShowroomItem item) { this.item = item;}
    public void doTransaction() {item.buy(); item.sell();}
}

class Driver {
    private Vehicle veh = null;
    public Driver(Vehicle veh) {this.veh = veh;}
    public boolean testDrive() {veh.start(); veh.stop(); return true;}
}

public class ShowroomOwner {
    public void makeDeal(Car carForDeal) {
        Driver driver = new Driver(carForDeal);
        SalesEngineer engineer = new SalesEngineer(carForDeal);
        if (driver.testDrive()) {
            engineer.doTransaction();
        }
    }

    public static void main(String[] args) {
        // simulates client as ShowroomOwner to save space
        new ShowroomOwner().makeDeal(new Car());
    }
}

在参考 Jim Arlow 的“UML 2 和统一过程”之后,我发现我们可以在序列图中的生命线上显示变化的状态。我觉得我们可以使用类似的符号来显示更改类型的对象 [我从未在 UML 中的任何地方看到过这种记录,但这是我对 UML 组的建议]。

例如这里 myCar 是其类 Car 的对象(对象的类永远不能改变),但它的引用类型根据左侧的 ShowroomItem 或 Vehicle 变化。

可能下面的时序图可以展示出来。 [示例类只是为了突出自动类型转换效果]

enter image description here

解决方法

UML 符号问题

您需要为序列图的每条生命线选择要显示的类型,因为 UML 只允许一个。由于 myCar 是实现 CarVehicleShowroomItem,因此您可以选择 3 种类型中的任何一种。

一旦选择了类型,UML 就无法在同一图表中提供有关该类型的替代视图。您可以显示 myCarCar 的场景。但是其他生命线必须符合它们所知道的接口(前提是没有其他使用依赖性使它们能够访问完整的 Car)并且由您来确保一致性。正如您使用 playMusic() 演示的那样,这可能容易出错。

您可以通过图表中的一个或多个注释来解决您的问题,以纯文本形式提醒读者与界面相关的约束。但更好的方法是保持简单,并在两个单独的区域显示 SalesEngineerCar 之间以及 DriverCar 之间的交互图表。这更接近您的设计的实际情况,并促进合理的关注点分离

OOP 设计问题

Qwerty_soBruno 已经指出了您设计中的弱点。我完全同意他们的看法。实际上,CarVehicle。但是 Car 不是 ShowroomItemCar 可以暂时具有陈列室物品的作用。或者反过来说,陈列室物品可能在给定时间对应特定的汽车。

如果汽车不是陈列室物品,它既不应该继承这样的类,也不应该实现这样的接口。因此,更喜欢composition over inheritance,例如:

  • SalesEngineer 交易 ShowroomItem
  • CarForSale 实现 ShowroomItem
  • CarForSale 与一个 Car
  • 相关联
  • Driver 驾驶 Vehicle警告:偏向滚动车辆,因为飞机上没有司机;-) )立>
  • Car 实现 Vehicle
  • Car 可以与 CarForSale 相关联(但前提是它由 SalesEngineer 出售)

这种设计确保了更好的关注点分离。例如,您可以只sell()buy() 只出售真正待售的汽车而不是任何汽车。只有待售的汽车才会有价格。

另一个优点是您可以在单个序列图中以更健壮的方式展示全貌,因为不同的职责由不同的对象实现

,

由于 CarShowRoomItem 继承(根据您的 UML),它也将具有 sell() 操作并且 SalesEngineer 可以使用它。

我觉得你的模型很奇怪。具有 sell() 操作的汽车绝对是我不会购买的。换句话说:你的类模型坏了。

,

首先你的类图是错误的,汽车不是ShowRoomItem,汽车在航行/购买前后是一样的,在你的情况下汽车将不得不停下来(可能是暂时的) 成为 ShowRoomItem,因为它是sail/buy。事实上,它是一个陈列室项目不是一种类型,而是一种状态,但对我来说,将这种状态作为汽车的一个属性也是一个错误的选择。

司机或销售工程师访问的第二个实际实例是一辆汽车,汽车并不关心谁使用它,当人是销售工程师时收音机不会消失,所以汽车总是接受播放收音机,如果足够前提条件是(电池有电,可能是钥匙打开等)

不能在车的层面上做人的限制,否则这是脱离现实的,完全是人为的,而是在人/角色的层面上。

在 UML 中,您可以使用约束来处理这种限制。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?