4

假设我有这样的设计:

对象 GUI 有两个对象:对象 aManager 和对象 bManager,它们从不相互通信。

aManager 和 bManager 都有对象 cManager 作为属性(或者更确切地说是指向 cManager 的指针)。因此,当 aManager 修改其 cManager 时,它也会影响 bManager 的 cManager。

我的问题是设计/实现它的正确方法是什么?

本来想把cManager做成GUI的一个属性,GUI在构造aManager和bManager的时候会传递一个指向cManager的指针。但是恕我直言,GUI与cManager无关,那么GUI为什么要把它作为一个属性呢?

我应该在这里使用特定的设计模式吗?

4

7 回答 7

1

我将尽可能简单地解释这一点,如果我没有回答您的问题,我深表歉意。

当你真正得到这个问题的答案时,这是你真正思考面向对象的第一步。

在 OO 中,当两个对象都“具有”另一个对象时,两者都引用另一个对象是完全可以接受的。OO 的诀窍是对象有自己的生命,它们是流动的,任何需要它们的人都可以保留对它们的引用。当被许多其他对象使用时,对象必须保持自身“有效”并保持稳定性。(这就是为什么像 String 这样的不可变对象如此出色的原因,它们总是与它们被创建时一样有效)

一个例外是,如果您使用 C++ 进行编码,因为您实际上必须手动释放对象,这意味着所有者可以监控每个对象的生命周期——这使得在 C++ 中的 OO 中“思考”非常困难。

[补充] 由于您指的是指针,我认为您正在使用 C++ 编程,这是不同的。在这种情况下,你是对的。让一位经理“拥有”您的共享对象的生命周期。在所有其他引用消失之前,它不能让该对象死亡。

您还可以使用引用计数。每当有人获得对您的对象的引用时,它就会调用“addReference”或其他东西,只要完成它就会删除引用。如果有人在计数为 1 时调用 removeReference,则对象可以自行清理。这可能与您在 C++ 中实现真正的 OO 样式分配/释放一样接近。虽然它非常容易出错。

我相信有图书馆可以做这种事情。

于 2008-09-18T16:28:27.803 回答
1

我建议只在你的 GUI 对象构造函数中将 cManager 作为参数传递,但不要维护对它的引用(这里是 Java 代码,但你明白了):

public GUI(CManager cManager)
{
    this.aManager = new AManager(cManager);
    this.bManager = new BManager(cManager);
    // don't bother keeping cManager as a field
}

我认为 Singleton 或 Factory 在这里都不合适。

于 2008-09-18T16:33:14.237 回答
1

小心使用单例(如果您想要简单的测试,则根本不使用!)

于 2008-09-18T16:37:36.080 回答
0

您可以根据需要使用工厂模式来请求 aManager 和 bManager 对 cManager 的引用。

http://msdn.microsoft.com/en-us/library/ms954600.aspx

于 2008-09-18T16:10:25.070 回答
0

您应该考虑将您的 GUI 与您的模型和实现分开。

如果在应用程序范围内只有一个 cManager,你可以让 cManager 成为单例。

于 2008-09-18T16:13:46.903 回答
0

如果不讨论您想要实现的目标,这很难回答。但是,我想说,按照你的说法,让 GUI 将指针交给 aManager 和 bManager 。

如果您正在尝试创建 GUI 并想知道如何将数据输入和输出,那么我可以推荐这个: http ://codebetter.com/blogs/jeremy.miller/archive/2007/07/25/the -build-your-own-cab-series-table-of-contents.aspx

我认为这主要是为 C# 用户编写的,但也适用于其他语言。我猜这可能比您的第一个 OO 应用程序需要的更高级。我认为您将不得不给自己买一本关于 OO 设计的书,并花一些晚上的时间来阅读它。

作为一个菜鸟,我建议你不要费心在第一次尝试以最完美的正确方式做所有事情,而只是让一些事情起作用。随着时间的推移(并大量阅读),您将了解什么使解决方案在不同标准下比其他解决方案更好。你的问题没有正确答案。

于 2008-09-18T16:19:22.710 回答
0

一般来说,在任何时候,任何可变对象都应该有一个明确定义的所有者(一个对象在其整个生命周期中通常会有多个所有者,其中第一个是构造函数,然后将所有权交给调用的代码它,等等)任何其他拥有对该对象的引用的东西都应该将该引用视为对其他人拥有的对象的引用。

有人可能会想,当从 C++ 转到 Java 或 .net 时,“嘿,酷——我不必再担心对象所有权了”,但事实并非如此。可变对象的所有权在基于 GC 的系统中与在非 GC 系统中一样重要。缺乏任何表达所有权的方式并不能免除程序员知道谁拥有什么的义务。它只会使履行该义务变得更加困难。

如果 cManager 是可变的,那么 aManager 应该拥有一个,bManager 持有对它的引用,并认为对其目标的任何更改都会影响 aManager 的 cManager,或者 bManager 应该拥有一个(aManager 持有引用等),或者某个其他实体应该拥有一个,aManager 和 bManager 都认为他们的更改影响了该其他实体所拥有的。

即使使用一种不承认任何所有权概念的语言或框架,在处理可变对象时也要始终以这样的方式思考。否则会招致混乱和灾难。

于 2013-01-04T22:20:06.003 回答