Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In Code Complete page 25, it's said that it's a good idea to be able to easily replace the regular user interface classes by a command line one.

Knowing its advantages for testing, what about the problems it may bring?

Will this extra work really pay off for web and mobile projects? What about small and medium projects; do the same rules apply? What if it makes your design more complex?

share|improve this question
1  
In Perl, this is just what tools like MooseX::Getopt and Plack::Handler::CLI are for. –  Ether Aug 22 '12 at 14:17
4  
If you build your program with a CLI first, the UI can be layered on top of it, giving much more flexibility than a UI that's deeply embedded in the program. This is much the same for web services. –  zzzzBov Aug 22 '12 at 14:26
23  
Always is a strong word. –  Mark Canlas Aug 22 '12 at 14:46
5  
Please note the original quote, which is: "The architecture should be modularized so that a new user interface can be substituted without affecting the business rules and output parts of the program. For example, the architecture should make it fairly easy to lop off a group of interactive interface classes and plug in a group of command line classes." So CC does not say you should prepare for replacing a GUI with a command line, it just says the architecture should accomodate changing the UI. The GUI->command line thing is just an example. –  sleske Aug 24 '12 at 12:22
1  
@Vandell I have the Second Edition of Code Complete and this is not mentioned on page 25. Which edition are you referring to? –  JW01 Aug 30 '12 at 15:52
show 4 more comments

17 Answers

up vote 36 down vote accepted

Being able to reuse functionality under different interfaces (e.g. GUI vs CLI vs REST) is not always necessary but nice to have and enable serendipitous reuse for a system, as other people find new ways to interact with it.

This has a few drawbacks that need to be weighted:

  1. It'll require additional abstraction layers (sometimes even tiers). While having these layers is good engineering practice they have an additional cost in development, understanding that may not lead to reduce effort in other areas (e.g. maintenance, reuse, testing) so it's worth to ponder a bit about it.
  2. Flow that's optimal for a medium may be awful for others. If the functionality was designed to support a GUI it may be too chatty for the web. Not all functionality is worthwhile in every medium.
  3. There's a trap in trying to define a generic converter between services and user interface, so one can define the service contract and derive automatically (or as much as possible) the UI for all mediums. Many projects wasted too much effort trying to build such frameworks and adding every possible customization to it as the requirements changed.

Having said that, in my experience implementing such layers always ended up paying the effort. In a couple of cases I managed to deploy systems on time because we ended up having to swap media (e.g. from Web Services integration to UI) a few weeks before the due date.

share|improve this answer
1  
As other comments have noted, it should increase code cohesion and reduce coupling. Both of these should make your code simpler, and easier to test. Flow is more a GUI concept, and usually should not be present in other functionality. –  BillThor Aug 23 '12 at 1:29
show 1 more comment

This is generally a good idea, yes.

By-metaphor, people may think of this as a form of RESTful design. .... it's not, per se, as a typical (G)UI could involve complex multi-stage transactions like account creation.

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

I once programmed a drag'n'drop UI metaphor in the browser. Very complex interaction rules on the back-end to make the UX feel natural. I solved this by making the site an API and the GUI was a full app that generated events upon action. A module caught these events and, on a timer, bundled them into 'API calls' (for network efficiency).

The result was a completely RESTful core system. The second upshot was that I had an interface for 3rd parties, that I could expose using affiliation profiles as per the business model.

share|improve this answer
add comment

There's a different way of looking at things. Rather than assuming that a command line is the only way to go, why not assume that speech control might be used instead? An entirely different paradigm is required then.

Before Jobs took over Apple, very sophisticated voice control mechanisms were being explored. Apple squelched this in favor of things like Siri.

Sigh.

Popular and obvious aren't always "best."

share|improve this answer
add comment

One advantage is that you will be forced to think about the flow of the UI from the user perspective. (What am I trying to achieve? What context do I need to set up? Given that context, how do I achieve the goal?)

There's a big difference between "create bank account" and "write ms word document". Even if you don't build a CLI, it may add value just to consider the "CLI context" needed. Models don't just live in the business object model!

share|improve this answer
add comment

No. Terrible bit of advice.

It's a bit yagni (You aren't going to need it).

Exposing a command line interface is not the same as structuring your app in a way that supports unit testing, or complies with any part of SOLID, or any programming practice I'd recommend.

It doesn't work for any UI that just wouldn't suit a command line interface. MS Paint is a really simple app, but how, in any situation, would you see a benefit to being able to control it from a command line?

It wouldn't help you implement scripting. It would actually hinder any progress in that direction.

The only positive thing is it appeared on page 25, so at least you get a warning that the rest of the book might be, ... smelly. I read it a long time ago and didn't like it, so I am biased.

share|improve this answer
1  
Agreed +100000000 –  acidzombie24 Aug 23 '12 at 1:05
3  
Scriptable MSPaint sounds really useful actually. –  RoundTower Aug 23 '12 at 5:10
show 5 more comments

Building on what Mason Wheeler said, being able to interact with an application via a command-line makes it very easy to automate tasks.

This is particularly useful in testing.

To give a practical example, if I want to run automated tests on an application, I may want to install the application automatically. To do this, I might pass in the following parameters, "myApplication.exe /silentinstall".

I might program it so that when I specify this command-line switch, an install is performed silently in the background, without the GUI installer. Any input to the installer (such as the install directory) could be picked up from an XML file perhaps.

Take another example. Microsoft Test Manager GUI (comes with Visual Studio) allows users to launch test runs from its GUI interface, but also provides a command-line interface to do the same thing (using a combination of command-line switches and inputs). This means I can whip together a PowerShell or DOS script to automate the launching of tests, and I could then create a scheduled task so that the scripts are run every night, perhaps.

Some applications have command-line switches which specify for an application to open with certain options (for example, I might use '/maximize' to open the application in a maximized window).

There are plenty of scenarios where a command-line interface could come in use. These are just some examples.

share|improve this answer
add comment

These days (at least for Java) it seems like sooner or later all programs add a web service (SOAP or Ajax or both) sooner or later. So in general yes think that way but a web service front end is more likely than a command line if you want a better mental metaphor... and a more likely one.

share|improve this answer
add comment

It depends on how useful the command line program would be. Some things, like plotting a route on a map, or playing a 3-d game, just don't lend themselves to a command-line interface. But other things, like system tools are much better from the command line than from a GUI, for the simple reason that they can be scripted.

Dr. Richard Hipp once said that his ideal GUI operating system was a blank desktop with an icon to open up command windows and another icon to open a web browser. I feel almost the same way. If it would be useful as a command-line program, and not too difficult to build that way, I would do it. The GUI could be a completely separate program, maybe built by someone else!

share|improve this answer
show 2 more comments

It depends and when I say it depends, it's not just a matter of having a couple edge cases, but it is very dependent upon the application and the target audience. Assuming that we are eliminating games from the equation then there is still a wide array of applications that you may be writing where a command like is unlikely or never going to be implemented. Off the top of my head, any application targeting a mobile (e.g. iOS, Android, etc.) environment is likely going to fall under this heading.

With that in mind, in the general software space, any application that is heavily dependent upon visualization (e.g. PowerPoint, Maya, etc.) is unlikely to ever see a command line replacement be implemented. In fact, in the case of graphics software such as Maya, it is arguable a good mental exercise to determine how a full and proper command line version would work and it may not be possible to do so from a user standpoint. Thus, it is clear that there are definitively common applications that can be encountered where a command like interface is unlikely to ever be seen, or desirable even if scripting of the application may be desirable.

Next, if we look at the suggesting form the standpoint of general software architecture, I can see where it would make sense to periodically ask yourself "How can I access this feature without the user interface?" In general, if there is no way to do it and it is not directly interacting with the user (e.g. gesture input) then you likely have a situation where the overall architecture needs to be improved. In order to allow for ease of testing you are going to want to be able to directly access command without going through the user interface, even though they may not be invoked though a command line. This generally means that a solid API needs to be in place and theoretically a good API should allow for access via command line or user interface. Furthermore, in the long run, you will save yourself time if you need to add a new user interface to the application.

At the end of the day, I think that what the suggestion is trying to get at makes sense (i.e. Have a good API and build your user interface off of that) but the word selection might have been a bit better to get the point across.

share|improve this answer
1  
I don't disagree in general, but one of the great strengths of Maya is the fact that it does, in fact, have a very strong scripting API (originally MELScript, now Python). –  jwd Aug 22 '12 at 17:39
show 1 more comment

Notice the phrase again: "[It']s a good idea to be able to easily replace the regular user interface classes by a command line one". It doesn't mean you have to write a CLI, just that you could do it easily.

So, what it says is that your UI should be decoupled from the rest of the code.

share|improve this answer
2  
I think you intended to do a comment, right? –  Julio Rodrigues Aug 22 '12 at 15:27
add comment

The only danger I see in doing this is that to get to a certain part in the UI, the user normally has to traverse other parts of the UI.

Where as the developer can just execute the UI directly. I've seen situations where a developer could not reproduce a users issue until they actually used the product.

So factor that in as well when creating tests.

share|improve this answer
add comment

One key advantage that doesn't seem to have been mentioned is that being able to do this pretty much enforces strict decoupling of the UI from the underlying code. One key advantage of this is that it means that if you need to significantly change the GUI (say iOS standards to OSX standards, or one graphical engine to another), that's all you need to change, as the underlying code isn't dependant on the layout of the UI. It can't be, because if it was, the command line tools wouldn't work.

Other than that, being able to automate tests is a key advantage.

share|improve this answer
5  
Yes, but all that validation is part of a good UI, which I've said you need to change. The backend code that stores (for example) the current state of the user's account, the algorithm for searching for items, the game's specific rules, etc. The key thing here is that if I have to switch from mouse/keyboard-based UI to touchscreen UI for a game, I should still be able to use the same backend engine for handling combat calculations and scoring, so I can focus on writing new event handlers that use the same underlying system. –  deworde Aug 22 '12 at 14:21
1  
that's by no means easy btw, I hate writing event handlers and form validation code much more than business code. (though i agree with you that they should be de coupled the way you described) –  Click Upvote Aug 22 '12 at 16:12
2  
@ClickUpvote To an extent it depends how you implement your GUI. A really thin GUI that just sends ValueChanged messages to a support class and receives ValueValid/ValueInvalid messages in response will be much easier to swap out that one that does all the validation in OnTextboxChanged events. –  Dan Neely Aug 22 '12 at 19:06
show 1 more comment

It depends.

Often we partition our programs as model/view/controllers or model/view/view/model. It seems that the model should permit command line access, but I am not as sure about the controller. Naturally, the view is what is being replaced.

Some difference may exist based on tool chain. Code Complete is a Microsoft Press book, so perhaps you are using Microsoft technologies for this GUI? If so, I think there might be a check box when you create the app for exposing interfaces via COM or DCOM. For some Microsoft technologies, I think resource tables and message passing are pretty intensively coupled with anything the Wizards help you rapidly prototype. I think it is getting better, but if you are maintaining MFC or Forms, it might hurt a bit.

In some cases your GUI based program might be a wrapper around a management interface or might have so little logic of its own, that there is not much to control by command line interface. Building a separate console app might be quicker and still let you script, test or use what is important.

The key point I guess is that the suggestion is not a rule. If you follow it, you should get easier unit and acceptance testing or a fall back interface for when you or a customer might prefer typing instead of clicking. If it pays for itself, do it. Good luck.

share|improve this answer
4  
-1: Code Complete is a language-agnostic book about programming craft. –  deworde Aug 22 '12 at 10:34
1  
He never said otherwise. –  Click Upvote Aug 22 '12 at 13:39
show 1 more comment

It's not extra work, just different work. If you do it right, not only will it not make it more complex, it will make it simpler because it will force you to decouple your design. Whether or not you actually implement the CLI, your design will be better off for making it possible to do so.

share|improve this answer
3  
-1 for several completely incorrect statements. Of course it will make it more complex. It is, after all, an additional requirement/feature. –  Boris Yankov Aug 31 '12 at 0:10
show 1 more comment

I think it is a good idea. Additionally being able to write a second, command line front end, ultimately proves the business logic is totally decoupled to any particular application server architecture.

share|improve this answer
add comment

Yes it's almost always a good idea.

If you follow this approach you will not likely have a business logic or data access in a same thread as GUI, and behind some GUI handler. This reason alone is worth investing in.

share|improve this answer
2  
What would be the advantage of that, if you're writing e.g. a text editor? –  nikie Aug 22 '12 at 7:47
4  
@nikie Because, for example, you could replace your WYSIWIG text editor view with a plain text or markup based front-end, and as long as it passed the same information to the underlying model, your existing infrastructure would continue to work. –  deworde Aug 22 '12 at 10:36
add comment

Completely aside from testing, the obvious advantage to this approach is that it will make your project automatable and scriptable. If I'm able to send command-line commands to a program, I can write up a script to perform complicated tasks much more easily (and more reliably!) than I could create a macro to automate the same thing on a GUI.

Whether or not that's actually worth doing, of course, depends entirely on whether or not you have a lot of users who would want to automate your program.

share|improve this answer
10  
A lot of applications use a plugin model for scripting. Usually the object model is exposed and a language like python is used to write the scripts. I don't think command line parameters will work for a non-trivial app. –  Pratik Aug 22 '12 at 8:33
1  
@Marnixv.R.: gestures are merely a convenient way to perform some action that could be specified by a command, e.g. 'Zoom in on 35.73N 118.23W'. A drawing could be input as commands, although it would be inconvenient. Still I think there is great utility in a conveniently scriptable interface, and very little labor needed to create one. –  kevin cline Aug 22 '12 at 15:36
7  
+1: Another key advantage is that it makes it easy to log the user actions, simplifying reproduction of production problems. –  kevin cline Aug 22 '12 at 18:41
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.