gpt4 book ai didi

java - 如何过度设计 shell

转载 作者:行者123 更新时间:2023-11-30 11:06:05 25 4
gpt4 key购买 nike

昨天我偶然发现了this question ,它询问使用 command design pattern 创建一个 OO shell* .

这让我很好奇,因为我一直讨厌我的 shell(一连串的 ifs 和 elses)。我 answered这个问题有一个完整的例子。

这里有一段描述主要思想的摘录

private final Writer writer = new BufferedWriter(new OutputStreamWriter(
System.out));
private boolean quit = false;

private Map<String, Command> commands = new HashMap<>();
{
commands.put("create", new CreateChat(this));
commands.put("join", new JoinChat(this));
commands.put("exit", new ExitCommand(this));
}

public void run() throws IOException {
try (Scanner s = new Scanner(System.in)) {
writer.write("> ");
writer.flush();
while (!quit && s.hasNextLine()) {
String input = s.nextLine().trim();

// get or default is java8, alternatively you could check for null
Command command = commands.getOrDefault(input, new UnknownCommand(this, input));
command.execute();

if (!quit)
writer.write("> ");
writer.flush();
}
}
}

不过,我并不完全满意。我更喜欢声明式解决方案,您可以在其中指定命令并将它们映射到 Command 的适当实例界面。

我的问题是,我不确定如何处理复杂的输入,例如

collect sample <sequence<double>>

collect sample 1.0 1.5 1.33 1.45

class teacher <name> pupils <name> <name> ...

我可以将命令实例交给 Reader对象,但我觉得阅读自己的输入不是他们的责任。他们应该有一个 CommandParameter对象等

但我不确定如何设计它。我曾经实现了一个二进制协议(protocol)解析库,它使用户能够通过 xml 定义协议(protocol),这似乎是一个解决方案(但很复杂)。

另一个问题是,如果 CommandParameter 出现格式错误,我该如何告诉用户格式错误发生的时间和地点?无法创建?


长话短说

所以以一个明确的问题结束:可以使用哪些设计模式来创建一个干净的 shell (以声明的方式),同时尊重所有常见的干净的代码规则(关注点分离、单一职责原则等)。

*with 'shell' 我的意思是 (java) 程序的一部分,它从 System.in 中读取预定义的命令。并调用模型/ Controller 上的相应方法。

最佳答案

大体上,在设计 shell 时有两种思路:

  1. Unix 哲学:“文本是通用界面”。大多数受 Unix 启发的工具从 stdin 读取文本并将文本输出到 stdout 以相互交互。这种将文本作为通用界面的哲学之所以出现,是因为这些工具是由大量异类作者用异类语言编写的,他们可能从未见过面或听说过彼此。一个工具可以是荷兰人用 C 写的,另一个是澳大利亚的一个团队用 Python 写的,还有一个是 Perl 脚本,在不同的论坛上被无数人传过和修改过,等等,他们需要互操作彼此。 Unix shell 具有强大的工具,可以转换文本流以将一个程序的输出提供给另一个程序(sed、grep 等)。缺点是每个工具都必须实现自己的解析。

  2. 基于对象的 shell,最著名的是 PowerShell,还有更传统的编程语言(如 Python、Ruby、Lisp)的 REPL。在这种理念下,​​您将在 shell 中拥有对象,而 shell 工具交换这些对象而不是文本。基于对象的 shell 通常更易于使用,假设工具的作者将他们的工具设计为可以一起使用(如果所有工具都是由一个作者或一个统一的作者组编写的,通常就是这种情况)。缺点是几乎所有内容都必须用一种语言或一组共享公共(public)运行时的语言(例如 .NET)编写。

无论哪种情况,设计模式都很简单。在 Unix shell 哲学中,工具在文件系统中以声明方式声明为程序,而 shell 只会执行这些程序。另一方面,在基于对象的 shell 哲学中,您需要动态导入类文件,并且需要使用内省(introspection),以便 shell 可以弄清楚如何调用该工具。

关于java - 如何过度设计 shell ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29411966/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com