コンポジットパターンの解説。受注クラスと受注明細クラスにより関連の説明

オブ脳 in PHP

関連

ProEvo > PHP Evo > オブ脳 in PHP > 関連

デザインパターンを説明する前にオブジェクト指向における関連と委譲について説明する必要があります。
ここでは例として受注と受注明細クラスの関連について説明します。


1. 演習について
1.1 受注と受注明細
1.2 クラスの作成
2. 明細の追加
2.1 機能の追加・変更点
2.2 ソースの変更
3. 実行する
3.1 マネージャークラスの作成
4.2 実行

1. 演習について

1.1 受注と受注明細

オブジェクト脳のつくり方」にしたがって受注およびそれに関連するクラスを作成します。
本文でのクラス図を参照してもらえばわかるように、受注・明細・注文者のクラスを作ります(実行用のマネージャークラスについては後で作成します)

1.2 クラスの作成

本文のクラス図を元に各クラスを作ります。まずは属性とコンストラクタだけのクラスを作成します。
なお、PHPではすべての属性がpublicなのでsetter/getterメソッドは作らないことにします。 作成したクラスは次のようになります。

Juchu.php
<?php
require_once 'Chumonsya.php';
require_once 'Meisai.php';

class juchu {
  var $no;                // 注文番号
  var $chumonsya;         // 注文者
  var $meisais = array(); // 受注明細

  function juchu($no)
  {
    $this->no = $no;
  }
}
?>
		
Chumonsya.php
<?php
class chumonsya {
  var $name;    // 注文者氏名
  var $address; // 注文者住所

  function chumonsya($name, $address)
  {
    $this->name = $name;
    $this->address = $address;
  }
}
?>
		
Meisai.php
<?php
class meisai {
  var $no;          // 明細番号
  var $productName; // 商品名
  var $price;       // 金額

  function meisai($no, $name, $price)
  {
    $this->no = $no;
    $this->productName = $name;
    $this->price = $price;
  }
}
?>
		

2. 明細の追加

2.1 機能の追加・変更点

クラス図中での関連は、クラスの属性を関連するクラスのオブジェクトにすることで 実現します。
ここで明細は1:nの関係なのでオブジェクトの配列として実現することになります。
またメソッドとして明細を追加するaddMeisaiを作成します。

2.2 ソースの変更

2.1の機能追加に伴い、ソースを変更します。
また安全のためユニットテストを追加します。
テストのソースは次のようになります。

alltest.php
<?php
// UnitTest
require_once 'PHPUnit/GUI/HTML.php';
require 'Tests/juchuTest.php';

// run Test Suites
$suite = array();
array_push($suite, new PHPUnit_TestSuite("juchuTest"));
$result = new PHPUnit_GUI_HTML($suite);
$result->show();
?>
		
Tests/juchuTest
<?php
require_once 'PHPUnit.php';
require_once 'Juchu.php';

class juchuTest extends PHPUnit_TestCase {
  var $juchu;
  function juchuTest($name)
  {
    $this->PHPUnit_TestCase($name);
  }

  function setUp()
  {
    $this->juchu = new Juchu(1);
  }

  function testMeisai()
  {
    $meisai1 = new meisai(1, "Thirller", 2000);
    $this->juchu->addMeisai($meisai1);
    $meisai2 = new meisai(2, "Dangerous", 2000);
    $this->juchu->addMeisai($meisai2);
    $meisais = array($meisai1, $meisai2);

    $this->assertEquals($meisais, $this->juchu->meisais);
  }
  //CUPPA:End of Test Suite
}
?>
		
上記のテストが通るようにソースを変更します。
ソースは次のようになります。
Juchu.php
<?php
require_once 'Chumonsya.php';
require_once 'Meisai.php';

class juchu {
  var $no;                // 注文番号
  var $chumonsya;         // 注文者
  var $meisais = array(); // 受注明細

  function juchu($no)
  {
    $this->no = $no;
  }

  function addMeisai($meisai)
  {
    $this->meisais[] = $meisai;
  }
}
?>
		
テストを実行します。下の画面のようにグリーンになれば変更は完了です。
[テストの結果]

3. 実行する

3.1 マネージャークラスの作成

受注を実行する"マネージャー"クラスを作成します。
これもユニットテストを作成してから、マネージャークラスを実装します。
ソースは次のようになります。

Tests/managerTest.php
<?php
require_once 'PHPUnit.php';
require_once 'Manager.php';

class managerTest extends PHPUnit_TestCase {
  var $manager;

  function managerTest($name)
  {
    $this->PHPUnit_TestCase($name);
  }

  function setUp()
  {
    $this->manager = new Manager();
  }

  function testManager()
  {
    $output_org = <<<__EOT__
受注伝票
受注番号: 1
注文者 : 牛尾 剛
注文者住所: 大阪府 箕面市

明細番号	注文商品	金額
1		Thriller	2000円
2		Dangerous	2000円
--------------------------------------
  合計金額			4000円

__EOT__;
    $output = $this->manager->main();
    $this->assertEquals($output_org, $output);
  }
  //CUPPA:End of Test Suite
}
?>
		
Manager.php
<?php
require_once 'Juchu.php';

class Manager {
  function main()
  {
    $juchu = new Juchu(1);
    $juchu->chumonsya = new Chumonsya("牛尾 剛", "大阪府 箕面市");
    $meisai1 = new Meisai(1, "Thirller", 2000);
    $juchu->addMeisai($meisai1);
    $meisai2 = new Meisai(2, "Dangerous", 2000);
    $juchu->addMeisai($meisai2);
    // 表示画面作成
    $output = <<<__EOT__
受注伝票
受注番号: {$juchu->no}
注文者    : {$juchu->chumonsya->name}
注文者住所: {$juchu->chumonsya->address}

明細番号	注文商品	価格

__EOT__;
    $total = 0;
    for ($i=0; $i<count($juchu->meisais); $i++) {
      $meisai =  $juchu->meisais[$i];
      $output .= $meisai->no . "\t\t" . $meisai->productName . "\t" . $meisai->price . "円\n";
      $total += $meisai->price;
    }
    $output .= "--------------------------------------\n";
    $output .= "合計\t\t\t" . $total . "円\n";
    return $output;
  }
}
?>
		
テストを実行します。下のようにグリーンの画面がでれば完了です。
[テストの結果]

4.2 実行

実行用のphpファイルrun.phpを作成し、実行します。
ソースは次のようになります。

run.php
<?php
require 'Manager.php';

$manager = new Manager();
echo "
";
echo $manager->main();
echo "
\n"; ?>
実行します、下のような画面がでれば成功です。 [実行結果] [デモ]

$Revision: 1 $
Last update: $Date: 2009-03-19 20:17:04 +0900 (譛ィ, 19 3譛 2009) $