外部に使いやすい機能を提供しよう
今までメーカーからExcelファイルで新規商品のデータを受け取り、商品登録用のシステムに登録するという運用になっているところ、 メーカーにPHPのプログラムを提供することで、メーカーから新商品のデータを受け取れるようにしようと思いました。
SDKを1から作るのも面倒なので、現在稼働中の商品登録用のシステムに「最小限の改修」をした状態で提供します。 どうしたら良いでしょうか?
Facadeパターン
Facadeパターンとは、複雑な処理を隠蔽しシンプルな窓口を作るパターンです。 たとえば既存の商品登録機能が下記のような場合を考えましょう。
/**
* 商品情報.
*/
class Product
{
private string $maker;
private string $productCode;
private string $productName;
private int $price;
public function getPrice(): int
{
return $this->price;
}
public function setPrice(int $price)
{
$this->price = $price;
}
public function getProductName(): string
{
return $this->productName;
}
public function setProductName(string $productName): self
{
$this->productName = $productName;
return $this;
}
public function getProductCode(): string
{
return $this->productCode;
}
public function setProductCode(string $productCode): self
{
$this->productCode = $productCode;
return $this;
}
public function getMaker(): string
{
return $this->maker;
}
public function setMaker(string $maker): self
{
$this->maker = $maker;
return $this;
}
}
/**
* 商品登録
*/
class ProductRegister
{
public function register(Product $product): void
{
// 登録処理.
echo "下記商品を登録します\n";
echo $product->getMaker();
echo "\n";
echo $product->getProductCode();
echo "\n";
echo $product->getProductName();
echo "\n";
echo $product->getPrice();
echo "\n";
echo "上記商品を登録しました\n";
}
}
$register = new ProductRegister();
$product = new Product();
$product->setMaker('CPUメーカーA');
$product->setProductCode('AAABBBCC');
$product->setProductName('はやいCPU');
$product->setPrice(30000);
$register->register($product);
メーカーが手軽に登録できるように、元のクラスとメソッドを修正せず、 メーカー名を設定する手間が無いようなクラスを作りましょう。
class CpuProductRegisterFacade
{
public static function register(string $productCode, string $productName, int $price): void
{
$register = new ProductRegister();
$product = new Product();
// 提供先メーカーの名前を固定で入力することで、引数の数を減らす
// 保守性を高めるためには直接文字列を設定するのではなく、
// 設定ファイルやオブジェクト定数にすべき
$product->setMaker('CPUメーカーA');
$product->setProductCode($productCode);
$product->setProductName($productName);
$product->setPrice($price);
$register->register($product);
}
}
// 一行で処理ができ、引数も1つで済むようになった(
CpuProductRegisterFacade::register('AAABBBCC', 'はやいCPU', 30000);
Facadeを作ることで、3つの引数だけで登録する事ができました。 今回の例はあまりにシンプルすぎて効果が分かりづらいですが、 既存の処理が複雑であればあるほどFacadeパターンは有効に働くでしょう。