假设您有一个创建/复制/移动文件的功能。 [逻辑]
对于应该复制/创建的文件已存在的情况,您想要求用户覆盖该文件。[(G)UI]
如果(G)UI和逻辑完全分开,您实施此方法的方法是什么?
我想到的第一件事就是MVC模式,但这意味着我需要在需要用户交互的时候使用它。
还有其他建议吗?
BTW:你将如何用非OO语言实现这一点?
答案 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)
从我所看到的,实际上有两个问题:
如果我们使用OO语言,有几个设计模式可以解决这两个特定问题。
所以真的是选择和混合最简单的一个满足需求,最适合语言。
实际上,如果以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
//
}