如何在UML对象和序列图中分别显示同一对象的引用类型和对象类型
该图显示了示例类图以及序列图中这些类的对象的用法 在上图中,myCar实例可以通过ShowroomItem的引用或接口车辆的引用来引用。因此,客户机驱动程序/销售工程师将获得功能访问权限 我同意在实现阶段(例如Java),这里不需要类型标识,我们将把myCar视为自己使用的基类型(任何一个接口)的实例 但在序列图中,(为了清楚起见),我无法指出我的汽车驾驶员的参考应为车辆,销售工程师的参考应为展厅项目 我在UML2.0书籍中搜索,没有找到合适的符号。根据目前的理解,我可以将其显示为“myCar:Vehicle”或“myCar:ShowroomItem”,但这并不表示其Car对象称为接口。此快捷命令并不强制要求playMusic在被称为Vehcile时不能工作 有什么符号来表示这种细节吗 由于我对所提供的任何答案都不满意,因此我尝试添加以下内容,以使问题更加清楚,解决答案中提出的一些异议,并提出解决方案供专家审查。 看这些评论,我觉得要么人们没有理解核心问题,要么我没有突出核心问题。首先,让我演示代码不会中断。下面的代码允许SalesEngineer使用sell()和buy()功能访问抽象,而驱动程序只使用start()和stop()功能访问抽象[以这种方式设计]。这是接口的一个强大功能,可以向不同的客户机发布不同的抽象。Java集合使用相同的多个基本类型,即TreeSet中的Object和Compariable,一个用于equals(),另一个用于实体上的compare()如何在UML对象和序列图中分别显示同一对象的引用类型和对象类型,uml,class-diagram,sequence-diagram,ooad,object-diagram,Uml,Class Diagram,Sequence Diagram,Ooad,Object Diagram,该图显示了示例类图以及序列图中这些类的对象的用法 在上图中,myCar实例可以通过ShowroomItem的引用或接口车辆的引用来引用。因此,客户机驱动程序/销售工程师将获得功能访问权限 我同意在实现阶段(例如Java),这里不需要类型标识,我们将把myCar视为自己使用的基类型(任何一个接口)的实例 但在序列图中,(为了清楚起见),我无法指出我的汽车驾驶员的参考应为车辆,销售工程师的参考应为展厅项目 我在UML2.0书籍中搜索,没有找到合适的符号。根据目前的理解,我可以将其显示为“myCar:
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的“UML2和统一过程”之后,我发现我们可以在序列图中显示生命线上的变化状态。我觉得我们可以用类似的符号来表示变化的对象类型[我在任何地方都没有看到UML中记录了这一点,但这是我对UML小组的建议]
e、 g.此处myCar是其类别Car的对象(对象类别永远不能更改),但其参考类型根据左侧的不同而不同,如展厅项目或车辆
可能下面的序列图可以显示出来。[示例类仅用于突出显示自动类型的铸造效果]
由于
汽车从ShowRoomItem
继承(根据您的UML),因此它还将具有sell()
操作,并且SalesEngineer
可以使用它
我觉得你的模型很奇怪。一辆有sell()
操作的车肯定是我不会买的。换言之:你的课程模型是坏的。首先,你的课程图是错误的,一辆车不是一个展厅项目,一辆车在出海/购买前后都是一样的,在你的情况下,由于它是出海/购买,汽车将不得不停下来(可能是暂时的)作为一个展厅项目。事实上,它不是一种类型,而是一种状态,但对我来说,将该状态作为汽车的属性也是一个错误的选择
第二,司机或销售工程师访问的实际情况是一辆汽车,汽车不关心谁在使用它,当这个人是销售工程师时,收音机不会消失,因此如果有足够的先决条件,汽车总是接受播放收音机(电池通电,可能钥匙打开等)
事实上,根据人是谁而定的限制不能在汽车的层面上进行,否则这是不真实的,完全是人为的,而是在人/角色的层面上
在UML中,对于这种限制,您可以使用约束。UML符号问题
您需要选择要为序列图的每条生命线显示的类型,因为UML只允许一个生命线。由于myCar
是一款实现Vehicle
和ShowroomItem
的Car
,因此您可以选择这三种类型中的任何一种
一旦选择了类型,UML就无法在同一个图中提供关于该类型的备用视图。您可以使用myCar
作为Car
显示场景。但是其他生命线必须符合他们知道的接口(前提是没有其他使用依赖项允许他们访问完整的汽车),并且由您来确保一致性。这可能容易出错,正如您在playMusic()
中所演示的那样
您可以通过图表中的一个或几个注释来解决您的问题,以纯文本形式提醒读者与接口相关的约束。但是更好的方法是保持它的简单性,并在两个单独的图表中显示SalesEngineer
和Car
之间以及Driver
和Car
之间的交互。这更接近您设计的实际情况,并促进声音关注点的分离
面向对象设计问题
并且已经指出了你设计中的弱点。我完全同意他们的看法。实际上,汽车
就是汽车
。但是汽车
不是展厅项目
:汽车可以临时扮演展厅项目的角色。或者,一个展厅项目可能在给定时间对应于一辆特定的汽车
如果汽车不是展厅项目,它既不应从此类继承,也不应实现此类接口。因此,请选择,例如:
SalesEngineer
交易ShowroomItem
CarForSale
实现ShowroomItem
CarForSale
与一辆Car
驾驶员
驾驶车辆