- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
昨天我偶然发现了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 时有两种思路:
Unix 哲学:“文本是通用界面”。大多数受 Unix 启发的工具从 stdin 读取文本并将文本输出到 stdout 以相互交互。这种将文本作为通用界面的哲学之所以出现,是因为这些工具是由大量异类作者用异类语言编写的,他们可能从未见过面或听说过彼此。一个工具可以是荷兰人用 C 写的,另一个是澳大利亚的一个团队用 Python 写的,还有一个是 Perl 脚本,在不同的论坛上被无数人传过和修改过,等等,他们需要互操作彼此。 Unix shell 具有强大的工具,可以转换文本流以将一个程序的输出提供给另一个程序(sed、grep 等)。缺点是每个工具都必须实现自己的解析。
基于对象的 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/
我正在开发适用于 Wordpress 的 PSD,并面临着根据颜色过度对齐背景图像或相反的问题。 在桌面上一切都很好,但在移动设备上背景图像变小了(我使用了 background-size: 100%
在标准 Modelica 流体流量源中,通常指定流量或压力。例如,以下边界设置(P 表示压力边界,F 表示流量边界)通常会围绕管道组件: P - 管道 - P F - 管道 - P 但是,有时在同一侧
我正处于设计基于 Azure 的应用程序的早期阶段。考虑到我可能预期的需求的变化性,Azure 吸引我的地方之一是它的可扩展性。因此,我试图保持事物松散耦合,以便我可以在需要时添加实例。 我看到的关于
我与 Xcode 4 dot notation code sense problem 正好相反!点符号的代码完成不仅显示属性,还显示我的方法(在每个完成的左侧标记 P 或 M 分别指示它是属性还是方法
我是一名优秀的程序员,十分优秀!