将业务与表示逻辑分开的最佳方法?

Posted

技术标签:

【中文标题】将业务与表示逻辑分开的最佳方法?【英文标题】:Best way to separate Business from Presentation Logic? 【发布时间】:2010-09-28 13:06:33 【问题描述】:

我想创建一个可以在本地和在线上运行的游戏。

我的第一个想法是创建一个接口,其中包含 GUI 用于业务逻辑所需的所有方法,然后具有网络实现和本地实现。

这适用于请求-响应消息。但是服务器发送的消息呢,我必须更新一些 GUI 组件(即 JLabels)?

我的第一个解决方案是实现侦听器,实现中的每次更改都会触发一个事件。 GUI 将适当地注册和更改其组件。但是,在业务逻辑中调用触发事件看起来有点不对。

我在正确的轨道上吗?因为我觉得我不是。有什么建议吗?

谢谢。

注意:客户端是一个简单的 Java Swing GUI。

【问题讨论】:

【参考方案1】:

您所描述的将有助于保持模型独立于演示问题的目标,这是一件好事。这也将在模型的设计、开发和维护期间为您提供帮助,因为您可以根据模型中的某些更改应该触发特定事件来编写单元测试,而不必担心屏幕上可能会是什么样子。

当然,它让您可以为不同的环境使用不同的 GUI 设计。

关键是事件应该与模型状态的变化有关,而而不是与表示级别的预期动作/表示有关。让表示层处理是否/如何响应模型事件。

【讨论】:

所以我在实现监听器方面走在了正确的轨道上?我一直听到的这个臭名昭著的 MVC 怎么样?我不确切知道如何实现它,但我想我应该在这样做之前先问清楚。 我同意 Joel 的观点 - 这是 mvc...您的视图正在监听模型,并自行更新。您的模型是业务逻辑。您的 GUI(菜单等)的其余部分与(或是)控制器部分对话,并与模型交互以对其进行操作。任何元素都可以独立于其他元素进行替换。 嗯.. 没想到这一点.. ;)【参考方案2】:

我承认我是做 Web 开发的,所以我对 Swing 没有太多经验。

但我一直认为我的处理方法是将应用程序分解为 /view、/model 和 /controller 包。这些关系将是单向的:/controller 会知道 /model 和 /view,但两者都不会从 /controller 或彼此导入任何类。

/view 层组件永远不会是 JFrame;它们总是 JPanel 或其他可以根据需要组合成 JFrame 的合适容器。每个都会引用 Listener 接口,在构造函数中初始化,并且会按照这些接口进行事件处理:

public class ExamplePanel extends JPanel implements ActionListener

    private JButton button;
    private ActionListener buttonListener;

    public ExamplePanel(ActionListener buttonListener)
        
        this.button = new JButton("Do Something");
        this.buttonListener = buttonListener;
        this.button.addListener(this.buttonListener);
    

    public void actionPerformed(ActionEvent e)
    
        this.buttonListener.actionPerformed(e);
    

这种安排适用于依赖注入,因为现在控制器可以选择使用该侦听器接口的本地或远程实现,以完全不影响客户端的方式更改行为。

我承认我从来没有一直遵循它。

Spring 人有一个丰富的 Swing 客户端模块,但它似乎已经失宠了。看起来他们已经决定 BlazeDS 方向是富客户的更好选择。但也许您可以从他们的方法中收集到一些设计理念。

【讨论】:

以上是关于将业务与表示逻辑分开的最佳方法?的主要内容,如果未能解决你的问题,请参考以下文章

sqlalchemy 模型的数据和逻辑分离

将业务逻辑与控制器解耦的最佳方式

将存储与业务逻辑分离的技术(RDBMS 和 NoSQL)

将业务规则与业务流程分开

业务逻辑和数据访问层的循环依赖

为啥不使用 GraphQL 作为业务逻辑层?