面向对象设计的GUI应用问题

5 投票
2 回答
785 浏览
提问于 2025-04-16 04:50

大家好,我正在为一个应用程序编写图形用户界面(GUI),这是一个可以放光盘的容器。目前我对面向对象设计的理解还不太清楚,需要一些帮助来理清思路。

首先,我使用观察者模式来构建抽象的模型和视图类,以及具体的模型(光盘容器)和具体的视图(光盘容器视图)。然后,我开始使用wxwidget框架来设计光盘容器的图形外观或布局(CDContainerWidget,来自wxPanel)和其他GUI控件(MainFrame,来自wxFrame)等。

现在我有三个类:CDContainerModel(光盘容器),CDContainerView(用于观察者模式的类),和CDContainerWidget(图形用户界面控件)。但我对CDContainerViewCDContainerWidget该怎么处理变得不太清楚了。

我认为CDContainerWidget和CDContainerView都需要CDContainerModel。我考虑了四种方法,但不知道哪种合适:

1). 将CDContainerWidget作为成员变量放入CDContainerView中,然后将CDContainerView作为成员变量放入Main Frame中。

class CDContainerView:
  def __init__:
     self.gui=CDContainerWidget

class MainFrame:
  def __init__:
     CDContainerView

2). CDContainerView继承CDContainerWidget:

class CDContainerView(CDContainerWidget):

class MainFrame:

   def __init__:

     CDContainerView

3). CDContainerWidget继承CDContainerView:

class CDContainerWidget(CDContainerView):

class MainFrame:
  def __init__:
     CDContainerWidget

4). 不使用CDContainerWidget和CDContainerView,而是使用一个单独的类CDContainerBig,继承抽象类View和wxPanel。

class CDContainerBig(View, wxPanel)

我的问题是,哪个解决方案是正确的?我看过MVC模式的维基页面,但并没有真正理解它的描述,也不知道如何应用它,同时也在想它是否适合我的问题。

另外,我补充一下,最开始我设计程序时没有想太多,直接选择了第二种方法。但现在我觉得第三种方法不错,因为把控件放在控件里(将CDContainerWidget放入MainFrame)是合理的。但我并不太确定。此外,似乎在观察者模式下,这三个类的关系有些复杂和尴尬。有时候我觉得这四种方法可能是一样的,只是包含关系或消息发送的方向不同。我觉得我真的需要在这一点上澄清一下。

我倾向于第三种方法,因为从实际出发,CDContainerWidget实际上包含几个子控件(按钮、输入框等),如果我们通过子控件设置新值,那么对于第一种方法,我们需要CDContainerWidget知道CDContainerView,以便让CDContainerView通知其他视图。第二种方法更糟,CDContainerWidget必须知道它的子控件CDContainerView。对于第三种方法,CDContainerWidget本身就是CDContainerView,这样是很合理的。第四种方法虽然简单,但没有逻辑上的分离。这是我自己的想法,不知道是否正确。

谢谢大家!!

2 个回答

1

选项1看起来最合适。一般来说,除非有特别的需求或者其他很好的理由,否则你应该尽量避免使用继承。过度使用继承会让你的代码变得过于紧密,导致后续的修改和维护变得困难。

1

为了让你更容易地减少类与类之间的紧密联系,可以考虑使用一种叫做信号-槽模式的东西,比如Spiff Signal,或者其他一些信号/槽模块。

通过将通信的逻辑分开,你就不再需要模块之间直接交流,而是可以通过消息传递和回调的方式来进行沟通。

撰写回答