このコードの問題点はexternalJoinTypeMethodメソッド内の依存性が外部の状態であるUserDefaultsに依存していることです。
これにより、メソッドの振る舞いが外部の状態に依存し、テストや保守が困難になる可能性があります。
<?php
enum AccountType: int
{
case PREMIUM;
case GENERAL;
}
<?php
class UserDefaults
{
private $data = [];
public function integerForKey($key)
{
if (array_key_exists($key, $this->data)) {
return $this->data[$key];
} else {
return 0; // デフォルト値を返す
}
}
public function set($value, $key)
{
$this->data[$key] = $value;
}
}
<?php
class Account
{
private $userDefaults;
public function __construct()
{
$this->userDefaults = new UserDefaults();
}
public function externalJoinTypeMethod(string $name): string
{
$acountType = $this->userDefaults->integerForKey("accountType");
switch ($acountType) {
case AccountType::PREMIUM:
return "$name さんは、プレミアム会員です.";
case AccountType::GENERAL:
return "$name さんは、一般会員です.";
default:
throw new Exception("このパターンは例外です.");
}
}
public function testExternalJoinTypeMethodForPremium()
{
$this->userDefaults->set(AccountType::PREMIUM, "accountType");
$result = $this->externalJoinTypeMethod("山田");
assert($result === "山田 さんは、プレミアム会員です.");
}
public function testExternalJoinTypeMethodForGeneral()
{
$this->userDefaults->set(AccountType::GENERAL, "accountType");
$result = $this->externalJoinTypeMethod("山田");
assert($result === "山田 さんは、一般会員です.");
}
}
<?php
$account = new Account();
$account->testExternalJoinTypeMethodForPremium();
$account->testExternalJoinTypeMethodForGeneral();
改善例として、externalJoinTypeMethodメソッドの内部でUserDefaultsに依存せず、メソッドの引数としてAccountTypeを渡す方法が考えられます。
これにより、メソッドは外部の状態に依存しないようになり、外部結合の問題を解消できます。
<?php
enum AccountType: int
{
case PREMIUM;
case GENERAL;
}
<?php
class Account
{
public function externalJoinTypeMethod(string $name, AccountType $acountType): string
{
switch ($acountType) {
case AccountType::PREMIUM:
return "$name さんは、プレミアム会員です.";
case AccountType::GENERAL:
return "$name さんは、一般会員です.";
default:
throw new Exception("このパターンは例外です.");
}
}
public function testExternalJoinTypeMethodForPremium()
{
$result = $this->externalJoinTypeMethod("山田", AccountType::PREMIUM);
assert($result === "山田 さんは、プレミアム会員です.");
}
public function testExternalJoinTypeMethodForGeneral()
{
$result = $this->externalJoinTypeMethod("山田", AccountType::GENERAL);
assert($result === "山田 さんは、一般会員です.");
}
}
<?php
$account = new Account();
$account->testExternalJoinTypeMethodForPremium();
$account->testExternalJoinTypeMethodForGeneral();