デザインパターンを説明する前にオブジェクト指向における関連と委譲について説明する必要があります。
ここでは例として受注と受注明細クラスの関連について説明します。
「オブジェクト脳のつくり方」にしたがって受注およびそれに関連するクラスを作成します。
本文でのクラス図を参照してもらえばわかるように、受注・明細・注文者のクラスを作ります(実行用のマネージャークラスについては後で作成します)。
本文のクラス図を元に各クラスを作ります。まずは属性とコンストラクタだけのクラスを作成します。
なお、PHPではすべての属性がpublicなのでsetter/getterメソッドは作らないことにします。
作成したクラスは次のようになります。
<?php
require_once 'Chumonsya.php';
require_once 'Meisai.php';
class juchu {
var $no; // 注文番号
var $chumonsya; // 注文者
var $meisais = array(); // 受注明細
function juchu($no)
{
$this->no = $no;
}
}
?>
<?php
class chumonsya {
var $name; // 注文者氏名
var $address; // 注文者住所
function chumonsya($name, $address)
{
$this->name = $name;
$this->address = $address;
}
}
?>
<?php
class meisai {
var $no; // 明細番号
var $productName; // 商品名
var $price; // 金額
function meisai($no, $name, $price)
{
$this->no = $no;
$this->productName = $name;
$this->price = $price;
}
}
?>
クラス図中での関連は、クラスの属性を関連するクラスのオブジェクトにすることで
実現します。
ここで明細は1:nの関係なのでオブジェクトの配列として実現することになります。
またメソッドとして明細を追加するaddMeisaiを作成します。
2.1の機能追加に伴い、ソースを変更します。
また安全のためユニットテストを追加します。
テストのソースは次のようになります。
<?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();
?>
<?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
}
?>
<?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;
}
}
?>
![[テストの結果]](images/composite1-01.jpg)
受注を実行する"マネージャー"クラスを作成します。
これもユニットテストを作成してから、マネージャークラスを実装します。
ソースは次のようになります。
<?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
}
?>
<?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;
}
}
?>
実行用のphpファイルrun.phpを作成し、実行します。
ソースは次のようになります。
<?php require 'Manager.php'; $manager = new Manager(); echo ""; echo $manager->main(); echo "\n"; ?>
[デモ]Copyright © 1997-2003 by A.G.Labo
$Revision: 1 $