SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

デザインパターンの使い方

デザインパターンの使い方: Facade

 リスト1に示すCommandクラスは、ProcessBuilderオブジェクトと、そのオブジェクトが作成するProcessオブジェクトとのやり取りを単純化するファサードです。

リスト1 Commandクラス
import java.io.*;

public class Command {
   private String[] command;
   private Process process;
   private StringBuilder output = new StringBuilder();
   private StringBuilder errorOutput = new StringBuilder();

   public Command(String... command) {
      this.command = command;
   }

   public void execute() throws Exception {
      ProcessBuilder processBuilder =
         new ProcessBuilder(command);
      process = processBuilder.start();
      collectOutput();
      collectErrorOutput();
      process.waitFor();
   }

   private void collectErrorOutput() {
      Runnable runnable = new Runnable() {
         public void run() {
            try {
               collectOutput(process.getErrorStream(),
                             errorOutput);
            }
            catch (IOException e) {
               errorOutput.append(e.getMessage());
            }
         }
      };
      new Thread(runnable).start();
   }

   private void collectOutput() {
      Runnable runnable = new Runnable() {
         public void run() {
            try {
               collectOutput(process.getInputStream(), output);
            }
            catch (IOException e) {
               output.append(e.getMessage());
            }
         }
      };
      new Thread(runnable).start();
   }

   private void collectOutput(InputStream inputStream,
      StringBuilder collector) throws IOException {
      BufferedReader reader = null;
      try {
         reader =
            new BufferedReader(new InputStreamReader(inputStream));
         String line;
         while ((line = reader.readLine()) != null)
            collector.append(line);
      }
      finally {
         reader.close();
      }
   }

   public String getOutput() throws IOException {
      return output.toString();
   }

   public String getErrorOutput() throws IOException {
      return errorOutput.toString();
   }
}

 このCommandクラス内のProcessBuilderに関連するコードは、それほど複雑ではありません。とはいえ、1つのコマンドを実行して結果を取得するだけならば、できればもっと簡単に済ませたいところです。Commandクラスを使用すれば、話はずっと簡単になります。

Command command = new Command("dir", "/");
command.execute();
System.out.println(command.getOutput());
System.out.println(command.getErrorOutput());

 Commandクラスのコンストラクタは、各コマンドラインパラメータを文字配列内の独立した文字列として受け取ります。

 ファサードは、オブジェクト指向設計における、情報隠蔽の概念の中核を占めるものです。ProcessBuilderクラスとProcessクラスは実装の詳細であり、Commandクラスというインターフェースによって、こうした詳細を「コマンドの実行」と「出力の取得」という抽象レベルまで単純化しています。

次のページ
テストとファサードの関係

この記事は参考になりましたか?

デザインパターンの使い方連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Jeff Langr(Jeff Langr)

本格的なソフトウェアの開発に四半世紀以上携わってきたベテランのソフトウェア開発者。『Agile Java: Crafting Code With Test-Driven Development』(Prentice Hall、2005年)と、他の1冊の著書がある。『Clean Code』(Uncle Bob Martin著、Prentice Hall、2008年8月)にも寄稿している。また、ソフトウェア開発に関する記事を80件以上執筆しており、そのうちの...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3376 2009/01/07 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー