SHOEISHA iD

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

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

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

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

  • X ポスト
  • このエントリーをはてなブックマークに追加

 Interpreterパターンは、言語の文法をオブジェクトで表現し、そのオブジェクトを用いて言語の文を解釈するためのデザインパターンです。本稿では、単純なブール言語をサポートするインタープリタの作成を例に、Interpreterパターンを解説していきます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

Interpreterパターンの例

 GoFの『オブジェクト指向における再利用のためのデザインパターン』では、Interpreterパターンは基本的にCompositeパターンと同じもので、その目的が違うだけだと紹介されています。Compositeパターンから結果として得られる階層構造が文法のようなものである場合、それはInterpreterパターンであると言えます。実際のところ、Compositeパターンのときに作成した例は、Interpreterパターンの実装例としても使えます。そういうわけで、本稿ではこれ以上の説明は必要なさそうです。

 しかし、ここで終わるわけにもいきません。というのは、開発者の皆さんにInterpreterパターンを理解してもらうのに役立つ、ちょうど良い例がほとんど紹介されていないからです。本稿の例は、完璧な例ではないかもしれませんが、「interpreter design pattern」と検索して見つけた例と比較すると、かなり分かりやすいのではないでしょうか。

 今回は、単純なブール言語をサポートするインタープリタの作成を目標にします。この言語は最終的に、動的な条件に基づいてフォルダ間で文書を移動させるための、簡単なコマンドセットの基礎となります。アプリケーションの例として「履歴書フィルタ」を考えてみます。例えば、次のようなコマンドがあるとしましょう。

move from incomingResumes to phoneScreen when
   contains fortran or smalltalk and olderThan 01/01/2006

 ここで、式の2行目、「contains」で始まる行に着目します。Interpreterパターンは、式から結果が1つだけ得られるようなものに最も適しているからです。

 今回の例では文書を扱うので、インタープリタの使い方を説明するために簡単な文書クラスが必要です。リスト1に、TextDocumentクラスの実装を示します。このクラスではcontainsメソッドをサポートし、作成日をカプセル化します。私はいつもテスト駆動開発をするようにしているので、TextDocumentクラスのテストも用意しました(リスト2)。

リスト1 Documentインターフェースとその実装クラス
// Document.java
public interface Document {
   public boolean contains(String... keywords);

   public java.util.Date getDate();
}

// TextDocument.java
import java.util.*;

public class TextDocument implements Document {
   private final String contents;
   private final Date date;

   public TextDocument(Date date, String contents) {
      this.date = date;
      this.contents = contents;
   }

   @Override
   public boolean contains(String... textElements) {
      for (String text: textElements)
         if (contents.contains(text))
            return true;
      return false;
   }

   @Override
   public Date getDate() {
      return date;
   }
}
リスト2 Containsのテスト
import static org.junit.Assert.*;

import java.util.*;
import org.junit.*;

public class ContainsTest {
   private static final String CONTENTS = "these are the contents";
   private TextDocument document;

   @Before
   public void createDocument() {
      document = new TextDocument(new Date(), CONTENTS);
   }

   @Test
   public void failsWhenTextNotInContents() {
      Expression expression = new Contains(CONTENTS + "x");
      assertFalse(expression.evaluate(document));
   }

   @Test
   public void passesWhenTextInContents() {
      String text = "contents";
      assertTrue(CONTENTS.indexOf(text) != -1);

      Expression expression = new Contains(text);
      assertTrue(expression.evaluate(document));
   }
}

 Interpreterパターンを使用してインタープリタを作成するための基本的な方法は、必要な文法を一連のクラスへと変換することです。1個のクラスは文法の各規則を表し、そのクラスのフィールドは規則の変換先のシンボルを表します。例えば、今回のサブ文法には次のような規則があります。

And ::= Expression 'and' Expression

 つまり、今回のInterpreterパターンの実装には、2つのフィールドを持つAndという名前のクラスがあり、それぞれのフィールドにはExpressionオブジェクトが1つずつ格納されます(私はいつも、「and」などのテキストを表す独立したオブジェクトを作成する代わりに、それを今回のAndのような規則クラスのコードに直接組み込むようにしています)。

会員登録無料すると、続きをお読みいただけます

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

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

メールバックナンバー

次のページ

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

  • X ポスト
  • このエントリーをはてなブックマークに追加
デザインパターンの使い方連載記事一覧

もっと読む

この記事の著者

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件以上執筆しており、そのうちの...

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

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

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/3291 2008/12/02 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング