假设您有一个创建/复制/移动文件的功能。[逻辑]
对于应该复制/创建的文件已经存在的情况,您想询问用户是否覆盖该文件。[(G)UI]
如果(G)UI 和逻辑完全分离,你的实现方法是什么?
我首先想到的是 MVC 模式,但这意味着我必须在需要用户交互的任何地方使用它。
还有其他建议吗?
顺便说一句:您将如何在非 OO 语言中实现这一点?
假设您有一个创建/复制/移动文件的功能。[逻辑]
对于应该复制/创建的文件已经存在的情况,您想询问用户是否覆盖该文件。[(G)UI]
如果(G)UI 和逻辑完全分离,你的实现方法是什么?
我首先想到的是 MVC 模式,但这意味着我必须在需要用户交互的任何地方使用它。
还有其他建议吗?
顺便说一句:您将如何在非 OO 语言中实现这一点?
如果 GUI 和逻辑真的分开了,那么这个问题就不应该出现。根据设计,程序应根据具有默认值的选项覆盖或不覆盖。如果 GUI 可用,则可以设置该选项。
事实上,虽然显而易见的方法是直接开始复制,但您可以先通过查找冲突,并检查目标设备是否有足够的可用存储空间。然后,如果出现问题,什么也不做,除非有 GUI,在这种情况下,您可以报告问题并询问是否继续。
如果您想要一个可以逐个文件调用 GUI 的设计,那么将围绕它的逻辑设计为一组 n 个进程,每个进程复制一个文件,并在错误报告中提供可选的 GUI部分。GUI 然后可以重新调用复制一个文件的逻辑。
这种方法[伪代码]怎么样:
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
//
}
我首先想到的是 MVC 模式,但这意味着我必须在需要用户交互的任何地方使用它。
这是一件坏事,为什么?分离 GUI 和逻辑正是MVC 模式的用途。不要仅仅因为它有一个长名称而害怕它——一旦你将 GUI 和逻辑分开,你就有了一个“视图”和一个“控制器”,至少,如果不是一个“模型”的话——如果你的应用程序有状态,你也有一个模型。你可能还没有对自己承认这一点。
在我看来,确实存在两个问题:
如果我们使用 OO 语言,有几种设计模式可以解决这两个特定问题。
因此,实际上它是根据需要选择和混合最简单且最适合该语言的一种。
实际上,如果以 C# 为例,我们可以像这样实现 Template Method 和 Observer 混合:
// 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++ 中,我猜是对一个类的引用。
我可以看到两种方式:
file_exists(...)
和copy_file(...)
。UI 端总是file_exists
先调用并询问用户是否复制文件是否已经存在。copy_file(bool force, ...)
,如果文件存在,默认情况下会失败。所以 UI 端调用默认版本的函数,检查是否失败,原因是什么,如果是因为文件已经存在,询问用户并使用force=true
.在非 OO 语言中,我将实现某种事件队列,其中父(或子,取决于您的设计)UI 在“忙碌”标志为真时轮询事件。这样的事件让对方在等待“他们回答”标志成真时做其他工作。当然,必须观察两个方向的一些超时以及互斥。基本上,这里暗示了非阻塞 I/O 的原则或你最喜欢的关于实际无锁编程的理论。
有一定程度的分离..进程可以通信。根据您选择的语言,您可以通过具有原始信号的关系 DB 共享内存段、信号量 .. 或 IPC。对于这样一个笼统的问题,很难说得更具体。
请参阅我的评论,需要更多信息,以便可以制作出适用于您选择的语言的答案。