January 22, 2021
Hot Topics:

Working With Design Patterns: Facade

  • By Jeff Langr
  • Send Email »
  • More Articles »

The ProcessBuilder-related code in the Command class isn't terribly complex. Still, to execute a single command and capture output, it's a bit more effort than I want to deal with. Using the Command class is much simpler:

   Command command = new Command("dir", "/");
Note: The constructor for Command takes each command-line parameter as a separate string in a string array.)

Facades go to the core of the notion of information hiding in OO design. The ProcessBuilder and Process classes represent implementation details. The Command class interface reduces these details to a small set of abstractions: execute a command and get its output.

Testing and Facades

A test-driven approach will likely result in the creation of facades. Test-driven development (TDD) involves designing a system by writing tests to demonstrate exercising a class through its public interface. A developer looking to succinctly express a concept or policy in a unit test may find that it needs translation—a facade—to map to an underlying API.

The tests for the Command class appear in Listing 2. An interesting aspect of the CommandTest class is that it uses itself as the command-line application to test. This "self shunt" eliminates dependency on an external application or OS.

Listing 2: CommandTest.

import static org.junit.Assert.*;

import org.junit.*;

public class CommandTest {
   enum TestName {
      testSingleLine("a short line of text"),
      testMultipleLines("line 1\\nline2\\n"),
      testLotsOfLines("") {
        String outputText() {
           final int lots = 1024;
           StringBuilder lotsBuffer = new StringBuilder();
           for (int i = 0; i < lots; i++)
              lotsBuffer.append("" + i);
           return lotsBuffer.toString();

      private String outputText;

      TestName(String outputText) {
         this.outputText = outputText;

      String outputText() {
         return outputText;

   private Command command;

   public static void main(String[] args) {
      TestName testName = TestName.valueOf(args[0]);

   private static String syserrOutput(TestName testName) {
      return testName.outputText.toUpperCase();

   private static String output(TestName testName) {
      return testName.outputText();

   public void successfullyExecutesSingleLine()
      throws Exception {

   public void successfullyExecutesMultipleLines()
      throws Exception {

   public void successfullyExecutesLotsOfLines()
      throws Exception {

   private void executeCommand(TestName testName)
      throws Exception {
      command = new Command(commandString(testName));

   private void verifyOutput(TestName testName)
      throws Exception {
      assertEquals(output(testName), command.getOutput());

   private String[] commandString(TestName testName) {
      return new String[] { "java", "-classpath",
            "\"" + System.getProperty("java.class.path")
               + "\"", "CommandTest",
            testName.toString() };

Figure 1: Facade

About the Author

Jeff Langr is a veteran software developer with over a quarter century of professional software development experience. He's written two books, including Agile Java: Crafting Code With Test-Driven Development (Prentice Hall) in 2005. Jeff is contributing a chapter to Uncle Bob Martin's upcoming book, Clean Code. Jeff has written over 75 articles on software development, with over thirty appearing at Developer.com. You can find out more about Jeff at his site, http://langrsoft.com, or you can contact him via email at jeff at langrsoft dot com.

Page 2 of 2

This article was originally published on February 21, 2008

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date