设计一种架构,认为可以将用户界面类替换为命令行界面,这是一个好主意吗?


92

在第25页的“代码完成”中,据说可以用命令行轻松替换常规用户界面类是一个好主意。

知道其测试优势,它可能带来什么问题呢?

这项额外的工作真的能为Web和移动项目带来回报吗?中小型项目呢?相同的规则适用吗?如果这会使您的设计更复杂怎么办?


2
在Perl中,这正是MooseX :: GetoptPlack :: Handler :: CLI之类的工具所适用的。
以太

4
如果您首先使用CLI构建程序,则UI可以在其之上分层,比深深嵌入在程序中的UI提供更多的灵活性。对于Web服务,这几乎是相同的。
zzzzBov 2012年

28
永远是一个有力的词。
马克·坎拉斯

8
请注意原始的引号,它是:“架构应模块化,以便可以在不影响业务规则和程序输出部分的情况下替换新的用户界面。例如,架构应使其变得相当容易。组交互式界面类,并插入一组命令行类。” 因此CC并没有说您应该准备用命令行替换GUI,而只是说该体系结构应该适应于更改UI。GUI->命令行只是一个例子。
sleske 2012年

2
@Vandell我有第二版的Code Complete,第25页没有提到。您指的是哪个版本?
2012年

Answers:


43

能够重用不同接口(例如GUI,CLI和REST)下的功能并非总是必要的,但拥有并实现系统的偶然重用是一件很愉快的事情,因为其他人发现了与之交互的新方法。

这有一些缺点,需要权衡:

  1. 它需要附加的抽象层(有时甚至是层)。尽管拥有这些层是良好的工程实践,但它们会增加开发成本,但了解可能不会减少其他领域(例如维护,重用,测试)的工作量,因此值得对此进行一些思考。
  2. 对于其他介质而言,最适合介质的流量可能很糟糕。如果该功能旨在支持GUI,则对于网络来说可能太闲谈了。并非每种功能都值得在每种媒体中使用。
  3. 试图在服务和用户界面之间定义通用转换器存在一个陷阱,因此可以定义服务协定并自动(或尽可能多地)导出所有媒介的UI。许多项目浪费了太多的精力来尝试构建这样的框架,并随着需求的变化对其进行各种可能的自定义。

话虽如此,以我的经验,实现这些层总是要付出很多努力。在某些情况下,我设法按时部署了系统,因为我们最终不得不在截止日期前几周交换媒体(例如,从Web服务集成到UI)。


2
正如其他评论所指出的那样,它应该增加代码内聚力并减少耦合。两者都应使您的代码更简单,更易于测试。Flow更像是一个GUI概念,通常不应出现在其他功能中。
BillThor 2012年

我不敢相信这还没有被提及,但这是Model-View-Controller体系结构的本质。关键是能够随意交换视图和控制器,以减少@BillThor所说的耦合。这是MVC的最佳用例。
Rudolf Olah

110

完全除了测试之外,这种方法的明显优势是它将使您的项目可自动化可脚本化。如果我能够向程序发送命令行命令,则可以编写脚本来比执行GUI上的宏来自动化相同任务的脚本更轻松(并且更可靠!)执行复杂的任务。

当然,这实际上是否值得做,完全取决于您是否有很多想要自动化程序的用户。


12
许多应用程序使用插件模型进行脚本编写。通常,对象模型是公开的,并且使用python之类的语言编写脚本。我认为命令行参数不适用于非平凡的应用程序。
softveda 2012年

另一个好处是可发现性。Sublime Text的Ctrl-Shift-P功能就是一个很好的例子。如果我想要一些晦涩的功能,而不必在菜单中进行搜索,则只需键入我认为会被调用的名称,即可看到命令(和快捷方式)并能够立即执行。
亚当·伊利

OpenDJ,这是一个基于Java的开源LDAP服务器,就是一个很好的例子:在确认对话框中,您可以在GUI中进行每次修改的命令行。
法兰克

1
@ Marnixv.R .:手势只是执行命令可以指定的某些动作的便捷方式,例如“放大35.73N 118.23W”。尽管不方便,但可以将图形作为命令输入。我仍然认为,在一个方便编写脚本的界面中有很大的用途,创建一个界面所需的工作量很少。
凯文·克莱恩

7
+1:另一个主要优点是,它使记录用户操作变得容易,从而简化了生产问题的重现。
凯文·克莱恩

81

这不是额外的工作,只是不同的工作。如果操作正确,不仅不但不会使其变得更复杂,还可以使其更简单,因为这将迫使您使设计脱钩。无论您是否实际实施CLI,都可以通过设计来实现。


4
-1表示几个完全不正确的语句。当然,这会使它更加复杂。毕竟,这是一个附加的要求/功能。
鲍里斯·扬科夫

@BorisYankov我认为他的意思是“复杂的”而不是“复杂的”-它们听起来相似并且含义重叠,因此它们有时容易混淆
Izkata

43

似乎没有提到的一个关键优势是,能够做到这一点几乎可以强制 UI与底层代码严格分离。这样做的一个主要优势是,它意味着如果你需要显著改变GUI(说iOS的标准OSX标准,或一个图形引擎到另一个),这是所有你需要改变,因为底层的代码是不依赖于用户界面的布局。它不可能是,因为如果是,命令行工具是行不通的。

除此之外,能够自动化测试是关键优势。


如果我错了,请纠正我,但是从一个GUI更改为另一个GUI仍需要进行大量工作,例如表单验证/显示错误消息,设置事件处理程序等
。–单击Upvote 2012年

5
是的,但是所有这些验证都是好的UI的一部分,我说过您需要更改。后端代码存储(例如)用户帐户的当前状态,搜索项目的算法,游戏的特定规则等。这里的关键是,如果我必须从基于鼠标/键盘的UI切换到在游戏的触摸屏UI上,我仍然应该能够使用相同的后端引擎来处理战斗计算和计分,因此我可以专注于编写使用相同基础系统的新事件处理程序。
deworde 2012年

2
顺便说一下,这绝非易事,我讨厌编写事件处理程序和表单验证代码,而不是编写业务代码。(尽管我同意您的观点,它们应该按照您的描述去耦合)
单击Upvote 2012年

2
@ClickUpvote在某种程度上取决于您如何实现GUI。一个非常瘦的GUI只是将ValueChanged消息发送到支持类并接收ValueValid / ValueInvalid消息作为响应,因此与在OnTextboxChanged事件中执行所有验证的GUI相比,它更容易替换。
丹·尼利

@ClickUpvote我非常同意,这就是为什么我希望能够专注于自己喜欢的事物,或者给予我讨厌的事物,所以我可以尽快完成它。
deworde

17

是的,这几乎总是一个好主意。

如果您采用这种方法,您将不太可能在与GUI相同的线程中以及某些GUI处理程序的后面进行业务逻辑或数据访问。仅这个原因就值得投资。


2
如果您正在编写文本编辑器,那么这样做的好处是什么?
nikie 2012年

5
@nikie例如,因为您可以将WYSIWIG文本编辑器视图替换为基于纯文本或标记的前端,并且只要它将相同的信息传递给基础模型,您的现有基础结构就可以继续工作。
deworde 2012年

5

我认为这是个好主意。此外,能够编写第二个命令行前端,最终证明了业务逻辑已完全与任何特定的应用程序服务器体系结构分离。


5

我这样做的唯一危险是,要进入UI的某个部分,用户通常必须遍历UI的其他部分。

开发人员可以直接在其中执行UI。我看到过这样的情况,开发人员在实际使用产品之前无法复制用户问题。

因此在创建测试时也要考虑到这一点。


3

不,糟糕的建议。

有点yagni(您将不需要它)。

公开命令行界面与以支持单元测试或符合SOLID的任何部分或我建议的任何编程实践的方式构造应用程序不同。

它不适用于仅不适合命令行界面的任何UI。MS Paint是一个非常简单的应用程序,但是在任何情况下,从命令行控制它都会有什么好处?

它不会帮助您实现脚本。实际上,这将阻碍该方向的任何进展。

唯一积极的一点是它出现在第25页上,因此至少您会得到警告,该书的其余部分可能会...有点臭。我很久以前读过它,但不喜欢它,所以我有偏见。


1
同意+100000000

4
实际上,可编写脚本的MSPaint听起来真的很有用。
RoundTower 2012年

IMO的最佳答案。自从我遵循“不要实施'YAGNI'”的口号以来,我有更多的时间专注于实际工作,甚至还有足够的时间进行大量的实验。试图变得聪明一点,这告诉我,大多数时候,客户想要的扩展名与之前提到的有所不同,因此,没有浪费时间在不需要的东西上。
topskip 2012年

PSPaint +命令行界面= AutoCAD
Vorac 2012年

-1(如果可以的话)请注意,它没有说“实现CLI和GUI”;它说:“用于实现备用用户界面,如CLI”。
马克·赫德

2

基于Mason Wheeler所说的,能够通过命令行与应用程序进行交互使自动执行任务变得非常容易。

这在测试中特别有用。

举一个实际的例子,如果我想在一个应用程序上运行自动化测试,我可能想自动安装该应用程序。为此,我可能会传入以下参数“ myApplication.exe / silentinstall”。

我可能会对其进行编程,以便当我指定此命令行开关时,无需GUI安装程序即可在后台静默执行安装。也许可以从XML文件中获取对安装程序的任何输入(例如安装目录)。

再举一个例子。Microsoft Test Manager GUI(Visual Studio附带)允许用户从其GUI界面启动测试运行,但还提供了一个命令行界面来执行相同的操作(使用命令行开关和输入的组合)。这意味着我可以一起整理一个PowerShell或DOS脚本以自动启动测试,然后可以创建一个计划任务,以便脚本可能每天晚上运行。

一些应用程序具有命令行开关,这些命令行开关指定使用某些选项打开应用程序(例如,我可能使用“ / maximize”在最大化窗口中打开应用程序)。

在很多情况下都可以使用命令行界面。这些只是一些例子。


1

再次注意以下短语:“这是一个好主意,能够通过命令行轻松替换常规用户界面类”。这并不意味着您必须编写一个CLI,只是您可以轻松地做到这一点。

因此,它的意思是您的UI应该与其余代码分离。


2
我想您打算发表评论,对吧?
朱利奥·罗德里格斯

1

这取决于并且当我说这取决于时,这不仅是几个案例的问题,而且还取决于应用程序和目标受众。假设我们从等式中消除了游戏,那么您可能正在编写各种各样的应用程序,这些应用程序不太可能或永远不会实现。在我的头上,任何针对移动(例如iOS,Android等)环境的应用程序都可能会落入此标题。

考虑到这一点,在一般软件领域中,任何高度依赖可视化的应用程序(例如PowerPoint,Maya等)都不太可能实现命令行替换。实际上,在使用诸如Maya之类的图形软件的情况下,确定完整和适当的命令行版本的工作方式是一项很好的脑力劳动,从用户的角度来看,这样做是不可能的。因此,很显然,即使在可能需要编写脚本的情况下,也很难遇到像命令界面这样的命令,或者在某些情况下,它们是必不可少的。

接下来,如果我们以通用软件体系结构的观点来看建议的形式,我可以看到定期问自己“在没有用户界面的情况下如何访问此功能?”的意义。通常,如果没有办法,并且它没有与用户直接交互(例如手势输入),那么您可能会遇到需要改进整体体系结构的情况。为了简化测试,即使您可能无法通过命令行调用它们,也希望能够不通过用户界面直接访问命令。通常,这意味着需要一个可靠的API,并且从理论上讲,一个好的API应该允许通过命令行或用户界面进行访问。而且从长远来看

归根结底,我认为建议的意图是有道理的(即拥有一个良好的API并以此为基础构建用户界面),但是选择单词可能会更好一些。


1
我一般不会不同意,但是Maya的一大优势是事实上它确实具有非常强大的脚本API(最初为MELScript,现在为Python)。
2012年

@jwd-我选择Maya是一个示例,因为几年前我用过它,如果您在同一思路上有更好的想法,请告诉我。也许布莱斯(Bryce)虽然不太了解?
rjzii 2012年

0

这取决于。

通常,我们将程序划分为模型/视图/控制器或模型/视图/视图/模型。似乎该模型应该允许命令行访问,但是我对控制器不确定。自然,视图将被替换。

基于工具链可能存在一些差异。Code Complete是一本Microsoft Press的书,所以也许您在为此GUI使用Microsoft技术?如果是这样,我认为当您创建用于通过COM或DCOM公开接口的应用程序时,可能会有一个复选框。对于某些Microsoft技术,我认为资源表和消息传递与向导向导可以帮助您快速制作原型的所有内容紧密结合在一起。我认为它会变得更好,但是如果您维护的是MFC或Forms,则可能会有所伤害。

在某些情况下,基于GUI的程序可能是管理界面周围的包装器,或者可能只有很少的逻辑,以致命令行界面控制的内容不多。构建单独的控制台应用程序可能会更快,但仍然可以让您编写脚本,测试或使用重要的内容。

我想关键是建议不是一个规则。如果遵循它,您或客户可能更喜欢键入而不是单击时,应该获得更简单的单元和验收测试或后备界面。如果它能收回成本,那就去做。祝好运。


4
-1:Code Complete是一门与语言无关的关于编程技巧的书。
deworde 2012年

1
他从没有说过。
点击Upvote 2012年

他的问题是针对UI开发的。。。deworde先生?
伊恩

0

这取决于命令行程序的有用程度。有些事情,例如在地图上绘制路线或玩3D游戏,只是不适合命令行界面。但是其他一些事情,例如系统工具,从命令行上比从GUI上好得多,原因很简单,因为它们可以编写脚本。

Richard Hipp博士曾经说过,他理想的GUI操作系统是一个空白的桌面,带有一个用于打开命令窗口的图标和另一个用于打开Web浏览器的图标。我的感觉差不多。如果它作为命令行程序有用,并且构建起来不太困难,我会这样做。GUI可能是一个完全独立的程序,可能是由其他人构建的!


为什么在地图上绘制路线不适合CLI自动化?类似的东西PlotRoute(startPoint, endPoint)非常简单。
梅森惠勒2012年

@MasonWheeler-我相信它会更像PlotRoute(startPoint, endPoint, chart)
Fabricio Araujo,

0

如今(至少对于Java而言),似乎所有程序迟早都会添加Web服务(SOAP或Ajax或两者)。因此,总的来说,是这样想的,但是如果您想要更好的心理隐喻,那么Web服务前端比命令行更可能...而且更有可能。


0

看事物有另一种方式。为什么不假设可以使用语音控制呢?然后需要一个完全不同的范例。

在乔布斯接手苹果之前,人们正在探索非常复杂的语音控制机制。苹果公司压制了它,以支持Siri之类的东西。

叹。

受欢迎和显而易见的不一定总是“最好的”。


使用命令行的主要原因之一是能够测试和编写软件功能。仅仅为了对软件进行单元测试或运行批处理脚本而录制我们声音的音频片段可能会有点尴尬(或至少在磁盘上很笨拙)。

0

通常,这是个好主意,是的。

用一个比喻,人们可能会认为这是RESTful设计的一种形式。....本质上不是,因为典型的(G)UI可能涉及复杂的多阶段交易,例如帐户创建。

Better that one stays away from multi-stage complexity through shopping-cart-like models for transactional setup.

我曾经在浏览器中编写过拖放式UI隐喻。后端上非常复杂的交互规则使UX变得自然。我通过将站点设置为API来解决此问题,而GUI是一个完整的应用程序,该应用程序会在发生操作时生成事件。一个模块捕获了这些事件,并在计时器上将它们捆绑到“ API调用”中(以提高网络效率)。

结果是一个完全RESTful的核心系统。第二个结果是我有一个针对第三方的界面,可以根据业务模型使用从属关系配置文件进行公开。


-1

优点之一是您将不得不从用户角度考虑UI的流程。(我想达到什么目的?我需要设置什么环境?在这种情况下,我如何实现目标?)

“创建银行帐户”和“写ms word文档”之间有很大的区别。即使您没有构建CLI,也可能只是考虑所需的“ CLI上下文”而增加了价值。模型不仅存在于业务对象模型中!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.