分离逻辑/ GUI和用户交互

时间:2009-10-21 09:03:43

标签: user-interaction

假设您有一个创建/复制/移动文件的功能。 [逻辑]

对于应该复制/创建的文件已存在的情况,您想要求用户覆盖该文件。[(G)UI]

如果(G)UI和逻辑完全分开,您实施此方法的方法是什么?

我想到的第一件事就是MVC模式,但这意味着我需要在需要用户交互的时候使用它。

还有其他建议吗?

BTW:你将如何用非OO语言实现这一点?

6 个答案:

答案 0 :(得分:1)

如果GUI和逻辑真的分开,那么这个问题永远不应该出现。根据设计,程序应根据具有默认值的选项覆盖或不覆盖。如果GUI可用,则可以设置该选项。

事实上,虽然明显的方法是只需要它并开始复制,但您可以首先查找冲突,并检查目标设备是否有足够的可用存储空间。然后,如果出现问题,请不要做任何事情,除非有GUI,否则您可以报告问题并询问是否继续进行。

如果你想拥有一个可以在逐个文件的基础上调用GUI的设计,那么设计围绕它的逻辑作为一组n个进程,每个进程复制一个文件,并且有一个可选的GUI。错误报告部分。然后,GUI可以重新调用复制一文件逻辑。

答案 1 :(得分:0)

我可以看到两种方式:

  • 您有两个功能file_exists(...)copy_file(...)。 UI端始终首先调用file_exists并询问用户是否复制该文件是否已存在。
  • 您只有一个函数copy_file(bool force, ...),如果文件存在,默认情况下会失败。所以UI端调用该函数的默认版本,检查它是否失败以及为什么,如果是因为该文件已存在,请询问用户并再次使用force=true

答案 2 :(得分:0)

在非OO语言中,我会实现某种事件队列,其中父项(或子项,取决于您的设计)UI在“忙”标志为真时轮询事件。这样的事件让对方在等待“他们回答”的旗帜实现时做其他工作。当然,必须观察两个方向的一些超时以及相互排斥。基本上,这里暗示了非阻塞I / O的原则或您最喜欢的实用锁定编程理论。

有分离程度..流程可以沟通。根据您选择的语言,您可以通过关系数据库与原始信号共享内存段,信号量或IPC。如此普遍的问题很难更具体。

请参阅我的评论,需要更多信息,以便能够以您选择的语言制作答案。

答案 3 :(得分:0)

  

我想到的第一件事就是MVC模式,但这意味着我必须在需要用户交互的地方使用它。

这是一个坏事,为什么?分离GUI和逻辑正是 MVC模式的用途。不要害怕它只是因为它有一个很长的名字 - 一旦你分离了GUI和逻辑,你有一个“视图”和一个“控制器”,至少,如果不是“模型” - 如果你的应用程序有状态,你也有一个模型。你可能还没有考虑过它。

答案 4 :(得分:0)

从我所看到的,实际上有两个问题:

  1. 我们有一个算法(逻辑),我们希望将一些操作和决定推迟到其他地方(例如用户通过UI)。
  2. 我们希望避免算法与其他东西之间的紧密耦合。
  3. 如果我们使用OO语言,有几个设计模式可以解决这两个特定问题。

    • 模板方法模式可以解决#1。它没有很好地解决#2,因为典型的实现是通过继承。
    • 观察者模式看起来也很有希望。

    所以真的是选择和混合最简单的一个满足需求,最适合语言。

    实际上,如果以C#为例,我们可以像这样实现Template Method和Observer hybrid:

    // This will handle extensions to the FileCopy algorithm
    abstract class FileCopyExtention
    {
     public abstract Response WhatToDoWhenFileExists();
    }
    
    
    // the copy function, pure logic
    public static void Copy(string source, string destination, FileCopyExtention extension) 
    {
     if (File.Exists(destination))
     {
      var response = _extension.WhatToDoWhenFileExists();
      if (response == overwrite)
       // overwrite the file
      else
       // error
     }
    }
    
    // This is our user-interactive UI extension
    class FileCopyUI : FileCopyExtention
    {
     public override Response WhatToDoWhenFileExists()
     {
      // show some UI, return user's response to the caller
     }
    }
    
    // the program itself
    void Main()
    {
     Copy("/tmp/foo", "/tmp/bar", new FileCopyUI());
    }
    

    作为主题的变体,您可以使用事件,代表或您选择的任何语言。

    在C中,这可能是一个函数指针,在C ++中是对类的引用。

答案 5 :(得分:0)

这种方法怎么样[伪代码]:

UIClass
{
    //
    // Some code
    //

    bool fileCopied = false;

    do {
        try {
            fileCopied = CopyFile(fileName);
        } catch (FileExists) {
            //
            // Ask "File exists! Overwrite?" If "No", exit do-loop
            //
        } catch (FileLocked) {
            //
            // Ask "File Locked! Repeat?",   If "No", exit do-loop
           //
        } catch (etc...) {
            //
            // etc.
            //    
        }
    } while (!fileCopied);

    //
    // Some code
    //
}

LogicClass
{
    //
    // Some code
    //

    bool CopyFile(string fileName)
    {
        //
        // copy file
        //
    }

    //
    // Some code
    //

}