当前位置: 首页 > 知识库问答 >
问题:

类图中的组成关系可以有循环吗?

暨正真
2023-03-14

我想为Java类图实现一个模型检查器。

有许多限制我已经考虑了一段时间。

希望有人能帮我搞清楚。

这里所有的循环,我的意思是只有一种关系的纯循环。

Q1:假设A类由B类组成,鉴于A类和B类是不同的类,B类有可能也由A类组成吗?而且,构图关系有可能有循环吗?

Q2:类图中的其他关系,如聚合、依赖和关联,怎么样?在这些关系中,周期的意义是什么?谁能举一些例子?

感谢您阅读我的问题,希望有人能帮助我。

共有1个答案

怀展
2023-03-14

Q1:假设A类由B类组成,鉴于A类和B类是不同的类,B类有可能也由A类组成吗?而且,构图关系有可能有循环吗?

严格来说,用UML术语…是的,但是你很难在代码中真正实现这一点。如果你问自己,“没有A,B能独立存在吗?”和“没有B,A能独立存在吗?”如果你能同时对这两个问题回答“不”,那么你可以有两个相互组成的类。因为一个必须能够独立存在,另一个才能由它组成,所以你不能两者都有。然而,由于组合和聚合在很大程度上是基于设计和上下文的,这并不是完全不可能的。例如,你可以有这样的东西:

B 包含对 A 的引用,A 包含对 B 的引用

public class A {
    B myB;
    String name = "A";

    public A(int num) {
        this.name += num;
    }

    public void setMyB(B b) {
        this.myB = b;
    }

    public B getMyB() {
        return this.myB;
    }

    public String getName() {
        return this.name;
    }
}

public class B {
    A myA;

    String name = "B";
    public B(int num) {
        this.name += num;
        myA = new A(num);
    }

    public A getMyA() {
        return this.myA;
    }

    public String getName() {
        return this.name;
    }
}

在这个例子中,我们使用一个定义的< code>String为类提供一个标识符,然后给它附加一个数字,只是为了显示一些唯一的ID。我们提供了允许我们访问< code>A和< code>B引用的方法,但是只有< code>B通过构造函数(composition)创建它对另一个的引用。

使用这个简单的测试:

public class Test {
    public static void main(String[] args) {
        A myA = new A(1);
        B myB = new B(2);

        B anotherB = new B(3);

        myA.setMyB(anotherB);

        System.out.println("A = " + myA.getName());
        System.out.println("A's B = " + myA.getMyB().getName());

        System.out.println("B = " + myB.getName());
        System.out.println("B'a A = " + myB.getMyA().getName());
    }
}

我们可以看到以下输出

A = A1
A's B = B3
B = B2
B'a A = A2

在此示例中,< code>A中的B引用是在< code>A的上下文之外创建的,并作为参数传入。如果我们删除了< code>myB,我们将失去对它的< code>A的引用,但如果我们删除了< code>myA(我们还有< code>anotherB)则不会。

假设我们从A中删除了setMyB()方法,并将其移到构造函数中……我们将有一个新对象的无限循环,您将得到一个StackOverflowError

您可能会发挥创意并尝试实现 Singleton 模式或其他一些限制创建对象数量的构造,但这样做意味着构造函数需要私有/隐藏,这会阻止其他类的扩展。使用静态字段来跟踪创建的数量可能会防止错误,但是您将丢失所有引用,而没有地方跟踪所有引用,最后,您永远不会有一个“完美”的组合,因为一个类将缺少其组件。

在所有这些“分析”之后,你最终会得出一个有意义的设计,而不是一个严格符合UML图上所画内容的设计。UML图是用来表达类之间的“关系”的。你在这里问到的“独特的”情况,即A使用B and B使用A,可能不会用UML建模来解决,但可能需要一些其他的设计工作。

Q2:类图中的其他关系,如聚合、依赖和关联,怎么样?在这些关系中,周期的意义是什么?谁能举一些例子?

关联关系实际上用于描述由组合、聚合、多对多、一对一等定义的关系类型,并且依赖于上下文。每个关联中循环的含义将取决于您的设计。

一般来说,依赖关系中的循环意味着类依赖于它自己。这可能是为了递归函数调用、单例设计模式实现,或者其他一些需要类引用自身的设计模式。

上面已经回答了聚合。它基本上意味着对象“使用”它聚合的任何内容。例如,公司聚合人员。当公司倒闭时,人们仍然存在。这种关系中的循环与我的示例中所示的类似,不同的是您将有对AB类的外部引用,它们作为参数传递给对AB的前两个引用。

底线是...UML 是显示类之间关系的工具。设计和实现将由此而来,并且您拥有使用UML建模的“有趣”关系的事实不会帮助您克服严重的设计障碍。

希望这有助于阐明您的问题。

 类似资料:
  • 我正在组装一个java小程序,使任务在工作中更快、更高效。 用户定义项目列表需要拆分成的三个组的大小。列表中的每个项目根据它被放入三个组中的哪个组具有不同的值。小程序需要显示哪个组合的总价值最高。 示例:带有列的二维整数数组;项目编号、第1组中的值、第2组中的值和第3组中的值。 这样,用户定义组1有3个插槽,组2有3个插槽,组3有2个插槽。 小程序应不按特定顺序显示以下解决方案 我可以管理一种效率

  • 我花了5个多小时试图解决这个问题。有什么问题吗? 我补充道: 组织。格拉德尔。configureondemand=true 但问题依然存在 建筑gradle(模块:应用程序) 建造。gradle(项目:myproject) //顶级构建文件,您可以在其中添加所有子项目/模块通用的配置选项。

  • 我试图为我的项目管理软件画一个类图,描述如下。它包含以下类别: 项目 - 软件 - 管理项目的人/她 - 从事项目工作的人员 以及以下关系/关联: > < li> 一个项目经理可能要管理多个项目,而一个项目只能由一个项目经理管理 项目经理可以将员工分配给他/她管理的项目 对于上面的关联,我创建了这个类图: < li >如何对第一个关联(在< code>ProjectManager和< code>P

  • 问题内容: 我在excel中有父子数据,该数据已加载到运行MS SQL Server的第3方系统中。数据表示有向(希望)非循环图。第三方意味着我在架构中没有完全自由的手。excel数据是其他文件的串联,并且存在以下可能性:在各个文件之间的交叉引用中,有人引起了循环- 即X是Y的子级(X-> Y),然后是其他地方(Y-> A- > BX)。我可以在Excel或SQL Server数据库上编写vb,v

  • 问题内容: 我有一个循环正在我的PHP代码中进行一些错误检查。原来看起来像这样… 这一切都很好,但是尽管有一个错误,它仍然可以循环通过。有没有办法摆脱循环? 问题答案: 您正在寻找break语句。

  • 我在用Guice辅助注射。下面是一个标准场景: 现在,我可以使用Guice factory调用,并通过Guice注入的实例轻松获得我的实例。 我的问题是:如果我希望引用正在创建的的实例,该怎么办?换句话说,我想要: 我当前的解决办法相当难看:我手动创建了一个,而不使用,然后使用获取实例,并在实例上调用方法。啊!