class Database { public function getByName(string $name) { // Get data from database } } class User { /** @var Database */ protected $db; public function __construct(Database $db) { $this->db = $db; } public function getByName(string $name) { return $this->db->getByName($name); } } %BUBCBTF 6TFS HFU#Z/BNF
class Database { public function getByName(string $name) { // Get data from database } } class User { /** @var Database */ protected $db; public function __construct(Database $db) { $this->db = $db; } public function getByName(string $name) { return $this->db->getByName($name); } } • Userクラスが欲しい のはデータ • データの取得元はど こでもいい • にも関わらずコード ではDatabaseクラス に依存している
class Database { public function getByName(string $name) { // Get data from database } } class User { /** @var Database */ protected $db; public function __construct(Database $db) { $this->db = $db; } public function getByName(string $name) { return $this->db->getByName($name); } } • Userクラスが欲しい のはデータ • データの取得元はど こでもいい • にも関わらずコード ではDatabaseクラス に依存している 6TFSΫϥε͕ຊʹඞཁͳͷ ʮHFU#Z/BNFΛ௨ͯ͡σʔλΛฦ͢ʯԿ͔
interface Repository { public function getByName(string $name); } class Database implements Repository { public function getByName(string $name) { // Get data from database } } • 「getByNameを通し てデータを得られる 何か」をInterfaceで 表現する • 各クラスはそれに従 い実装する
interface File { public function open(string $filename); public function read(int $count); public function close(); } Example - 最⼩のInterface open, read, close関数を駆使すれば 1⾏ずつ読み込むことができる
interface File { public function open(string $filename); public function read(int $count); public function readLine(int $lineNum); public function close(); } Example - 完全なInterface
interface File { public function open(string $filename); public function read(int $count); public function readLine(int $lineNum); public function close(); } Example - 完全なInterface readLine関数で⼀⾏ずつ読むのは簡単!
interface File { public function open(string $filename); public function read(int $count); public function readLine(int $lineNum); public function close(); } Example - 完全なInterface readLine関数で⼀⾏ずつ読むのは簡単! ҰํͰ࣮ͱςετͷՃɺ ͦΕͷอकίετ͕ൃੜ͢Δ
interface Image { public function setWidth(int $width); public function setHeight(int $height); public function setName(string $name); } Example - 単純なInterface
interface Image { public function setWidth(int $width); public function setHeight(int $height); public function setName(string $name); } Example - 単純なInterface 縦と横のサイズ、名前だけ変更できる
interface Image { public function setWidth(int $width); public function setHeight(int $height); public function setName(string $name); public function setBrightness(int $level); public function setPixel(int $pixel); public function setEffect(string $effect); public function setExtension(string $ext); } Example - 複雑なInterface
interface Image { public function setWidth(int $width); public function setHeight(int $height); public function setName(string $name); public function setBrightness(int $level); public function setPixel(int $pixel); public function setEffect(string $effect); public function setExtension(string $ext); } Example - 複雑なInterface 画像に対して細やかな調整が可能!
interface Image { public function setWidth(int $width); public function setHeight(int $height); public function setName(string $name); public function setBrightness(int $level); public function setPixel(int $pixel); public function setEffect(string $effect); public function setExtension(string $ext); } Example - 複雑なInterface 画像に対して細やかな調整が可能! ҰํͰΠϯλʔϑΣʔεΛ ཧղ͢Δͷ͕͍͠
interface Person { public function getName(): string; public function setName(string $name); public function getRole(): string; } Person Interface おさらい:実現したいこと 「その⼈が特定の役割を持つか確かめる⼿段が欲しい」
class Manager { public function assign(Person $person) { if ($person->getRole() === 'admin') { // } } } 使い⼿の気持ちになる 最⼩/完全という観点で⾒ると最⼩と⾔えそうだが そもそも現時点でgetRole()を求められていない
interface Person { public function getName(): string; public function setName(string $name); public function isRole(string $role): bool; public function isAdmin(): bool; } Person Interface
interface Person { public function getName(): string; public function setName(string $name); public function isRole(string $role): bool; public function isAdmin(): bool; } Person Interface これは必要…? 今回の要件には含まれていない
interface Person { public function getName(): string; // public function setName(string $name); public function isRole(string $role): bool; public function isAdmin(): bool; } Person Interface
interface Person { public function getName(): string; public function isRole(string $role): bool; public function isAdmin(): bool; public function isSysAdmin(): bool; public function isGeneral(): bool; } Person Interface
interface Person { public function getName(): string; public function isRole(string $role): bool; public function isAdmin(): bool; public function isSysAdmin(): bool; public function isGeneral(): bool; } Person Interface 予測できる未来として「役割の種類が増える」ことが 考えられる
interface Person { public function getName(): string; public function isRole(string $role): bool; public function isAdmin(): bool; public function isSysAdmin(): bool; public function isGeneral(): bool; } Person Interface 仮に役割が増えるとすると、 Interfaceの完全さを保とうとすればするほど メソッドは増え、保守性は下がる