SHOEISHA iD

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

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

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

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

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

 アプリケーションを作成する上で条件ロジックを欠くことはできません。しかし、あまりに多用すると入り組んできて分かりにくくなります。このような事態をできるだけ避けるために、私はStateデザインパターンを使ってコードをすっきりさせています。本稿では、Stateデザインパターンの利用方法を例を示しながら説明します。

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

Stateパターンの例

 アプリケーションを作成する上で条件ロジックを欠くことはできません。しかし、あまりに多用すると入り組んできて分かりにくくなります。私が作成する多くのアプリケーションでは、オブジェクトはさまざまな状態で存在し、状態ごとにそれぞれ異なる動作をします。if文と複雑な条件分岐を多用する「直球型」の実装では、すぐに複雑怪奇なソリューションになってしまいます。このような事態をできるだけ避けるために、私はStateデザインパターンを使ってコードをすっきりさせています。

 図書館の取り置き本を例に説明しましょう。取り置き本(Holding)オブジェクトは、本(Book)オブジェクト(リスト1を参照)のコピーです(今回の実装では、BookはISBNの分類情報にすぎません。従って、各Holdingオブジェクトはコピー番号とBookオブジェクトを参照します)。Holdingオブジェクトの状態として、貸し出しと返却があります。図書館と図書館の間での移動もあります。利用者に所持されたり、保管庫に入れられたりもします。これらの各イベントによって、Holdingオブジェクトはさまざまな規則が適用される状態に遷移します。例えば、「貸し出し中」状態の本を保管庫で保管することはできません。

リスト1 Bookクラス
// BookTest.java
import static org.junit.Assert.*;
import org.junit.*;

public class BookTest {
   public static final Book CATCH22 = new Book("0-671-12805-1",
      "Catch-22", "Heller, Joseph", "1961");

   @Test
   public void create() {
      assertEquals("0-671-12805-1", CATCH22.getIsbn());
      assertEquals("Catch-22", CATCH22.getTitle());
      assertEquals("Heller, Joseph", CATCH22.getAuthor());
      assertEquals("1961", CATCH22.getYear());
   }
}

// Book.java
public class Book {
   private final String isbn;
   private final String title;
   private final String author;
   private final String year;

   public Book(String isbn, String title, String author,
      String year) {
      this.isbn = isbn;
      this.title = title;
      this.author = author;
      this.year = year;
   }

   public String getIsbn() {
      return isbn;
   }

   public String getTitle() {
      return title;
   }

   public String getAuthor() {
      return author;
   }

   public String getYear() {
      return year;
   }
}

 リスト2に、Holdingの最初の実装を示します(利用者IDとの関連はまだ考慮していません)。

リスト2 Holdingの最初の実装
import static org.junit.Assert.*;
import java.util.Date;
import org.junit.*;

public class HoldingTest {
   private Holding holding;
   private static final Date NOW = new Date();
   private static final String PATRON_ID = "12345";

   @Before
   public void initialize() {
      Book book = BookTest.CATCH22;
      int copyNumber = 1;
      holding = new Holding(book, copyNumber);
   }

   @Test
   public void create() {
      assertSame(BookTest.CATCH22, holding.getBook());
      assertEquals(1, holding.getCopyNumber());
      assertFalse(holding.isOnLoan());
   }

   @Test
   public void checkout() {
      holding.checkout(NOW, PATRON_ID);
      assertTrue(holding.isOnLoan());
      assertEquals(NOW, holding.getLoanDate());
   }

   @Test
   public void checkin() {
      Date later = new Date(NOW.getTime() + 1);
      holding.checkout(NOW, PATRON_ID);
      holding.checkin(later);
      assertFalse(holding.isOnLoan());
   }
}

// Holding.java
import java.util.Date;

public class Holding {
   private final Book book;
   private final int copyNumber;
   private Date checkoutDate;

   public Holding(Book book, int copyNumber) {
      this.book = book;
      this.copyNumber = copyNumber;
   }

   public Book getBook() {
      return book;
   }

   public int getCopyNumber() {
      return copyNumber;
   }

   public boolean isOnLoan() {
      return checkoutDate != null;
   }

   public Date getLoanDate() {
      return checkoutDate;
   }

   public void checkout(Date date, String patronId) {
      checkoutDate = date;
   }

   public void checkin(Date date) {
      checkoutDate = null;
   }
}

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

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

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

メールバックナンバー

次のページ

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

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

もっと読む

この記事の著者

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/3303 2008/12/12 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング