设计/实现与同一对象具有“关系”的两个(或更多)类的正确方法是什么?

时间:2008-09-18 16:08:15

标签: design-patterns oop

假设我有这样的设计:

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

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

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

我正在考虑将cManager作为GUI的一个属性,并且GUI在构造aManager和bManager时传递指向cManager的指针。但是恕我直言,GUI与cManager无关,那么GUI为什么要将它作为属性?

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

7 个答案:

答案 0 :(得分:1)

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

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

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

唯一的例外是,如果您使用C ++进行编码,那么您实际上必须手动释放对象,这意味着可以监视每个对象生命周期的所有者 - 这使得在C ++中的OO中“思考”真的很难。

[添加]因为你指的是指针,我认为你是用C ++编程的,这是不同的。在那种情况下,你是对的。让一个经理“拥有”共享对象的生命周期。在所有其他引用都消失之前,它不能让该对象死掉。

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

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

答案 1 :(得分:1)

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

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

我认为单身人士或工厂都不合适。

答案 2 :(得分:1)

小心使用单身人士(如果你想进行简单的测试,可以根本不使用!)

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分: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应用程序需要的更高级。我想你将不得不自己写一本关于面向对象设计的书,并花一些时间来处理它。

作为一个菜鸟,我建议你不要在第一次尝试以最完美正确的方式做任何事情,但只是得到一些工作。你会随着时间的推移(并经常阅读)学习什么使得解决方案比其他标准更好。你的问题没有正确答案。

答案 6 :(得分:0)

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

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

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

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