【发布时间】:2021-04-22 14:35:43
【问题描述】:
在上图中,myCar 实例可以通过ShowroomItem 的引用或接口Vehicle 的引用来引用。因此,客户 Driver/SalesEngineer 将获得功能访问权限。
我同意在实现阶段(例如 Java),此处不需要类型标识,我们将 myCar 视为自己使用的基类型(任一接口)的实例。
但在序列图中,(为了清楚起见)我无法指出 Driver 的 myCar 的引用应该是 Vehicle 和SalesEngineer 应该是 ShowroomItem。
我在 UML 2.0 书籍中搜索,我没有得到合适的符号。根据目前的理解,我可以将其显示为 "myCar : Vehicle" 或 "myCar : ShowroomItem",但这并不表示它的汽车对象称为接口.此缺点并不强制 playMusic 在称为 Vehcile 时无法工作。
是否有任何符号可以显示这种细节?
由于我对所提供的任何答案都不满意,我正在尝试添加以下内容以使问题更加清晰,解决答案中提出的一些异议,并提出一种解决方案供专家审查。
查看 cmets,我觉得要么人们没有得到核心问题,要么我没有突出核心问题。首先让我演示代码不会中断。以下代码允许 SalesEngineer 使用 sell() 和 buy() 功能访问 Abstraction,而 Driver 可以仅使用 start() 和 stop() 功能访问 Abstraction [以这种方式设计]。这是向不同客户端发布不同抽象的接口的一个最强特性。 Java 集合使用相同的多种基本类型,即 TreeSet 中的 Object 和 Comparable,一种用于 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。
可能是下面的序列图可以显示它。 [示例类只是为了突出自动类型转换效果]
【问题讨论】:
-
PlayMusic大写 P 确实是无处可去。但是playMusic绝对是基类的操作!概括也应该是实现。 -
是的@qwerty_so 你是对的。关于实现。接受错误。我会尝试更正图表。但是 playMusic() (接受错字)我故意没有添加到基类中以表明它不能在基类 ref 上调用。这是一个演示代码来说明我的观点..
-
编辑图片
-
不过,playMusic 是合法的操作。困惑。
-
I feel either people did not get the core question, or I failed to highlight the core issue:考虑到所有三个我们“没有得到核心问题”显然问题来自您的问题。This is a strongest feature of interfaces to publish different abstractions to different clients:这绝对是错误的,一个接口不知道“客户”也不关心他们,你混淆了接口和接口实现。changing states over life line in sequence diagrams.:您在图表中使用的符号/概念不是标准的一部分,类型不是状态
标签: uml class-diagram sequence-diagram ooad object-diagram