Upload
nelson-senna-do-amaral
View
126
Download
0
Tags:
Embed Size (px)
Citation preview
InterfacesComo objetos se comportam deveriam se comportar
Nelson Senna
• Github: https://github.com/nelsonsar
• Twitter: https://twitter.com/nelson_senna
• Tripda: https://tripda.com.br
• Membro do PHPSP
• Moderador eventual do PHP Brasil no Facebook
Motivação
Um pouco de teoria…
Assim como nós humanos, sistemas se
comunicam
Apesar de ter variantes, a comunicação de maneira simplista
se resume em passar uma mensagem
Emissor -> Mensagem -> Receptor
Mas, para que a comunicação seja bem sucedida o emissor
precisa ter prévio conhecimento do receptor
Ou, em outras palavras o receptor precisa ser capaz
receber a mensagem
“Hmm… Exemplo?”
<?php
class Teenager { public function listenToKatyPerry() { // Teenager knows this kinda of music } }
$teenager = new Teenager; $teenager->listenToLedZeppelin(); // The line above outputs: Fatal error: Call to undefined method Teenager::listenToLedZeppelin
A interface da classe Teenager não contemplava o
comportamento de escutar Led Zeppelin
Interfaces definem comportamento
E possibilitam a comunicação, já que mostram qual mensagens o
receptor pode receber
E como definir interfaces?
Primeiro você tem que respeitar as leis!
Uma interface deve fazer o que seu método diz que faz
<?php
class FileReader { public function readLine() { $f = fopen('/tmp/file', 'w'); fputs($f, 'bullshit'); } }
(╯°□°)╯︵ ┻━┻
A implementação de uma interface não deve causar mal
<?php
class FileReader { public function readLine() { $f = fopen('/tmp/file', 'r'); $totalNumberOfBytes = filesize('/tmp/file'); $numberOfReadBytes = 0; $line = ''; while ($totalNumberOfBytes != $numberOfReadBytes) { $byte = fgets($f, 1); if ($byte == PHP_EOL) return $line; $line .= $byte; }
return $line; } }
(╯°□°)╯︵ ┻━┻
Uma interface tem que notificar quem a chama se não conseguir
executar o que foi pedido
<?php
class FileReader { public function readLine() { $f = @fopen(‘/tmp/file', ‘r’);
if (!$f) return ‘’;
// code to read a line } }
(╯°□°)╯︵ ┻━┻
Segundo, ela tem que ser coesa*!
Os métodos nela devem ter um conceito em
comum
<?php
interface FileReader { public function readLine(); public function sendEmail(); }
(╯°□°)╯︵ ┻━┻
Quantos métodos ela tem que ter?
Depende…
Você prefere uma interface mínima ou uma completa? Uma simples
ou complexa? Stateless ou stateful?
Mínima
<?php
interface File { public function open(); public function read(); public function write(); public function close(); }
Completa
<?php
interface File { public function open(); public function read(); public function readLine(); public function readFrom($fromBytes); public function write(); public function writeLine(); public function close(); }
Mínima
<?php
interface ConnectionInterface { public beginTransaction() public commit() public excuteQuery($statement, array $params) public rollBack() }
Completa
<?php
class PDO { public beginTransaction() public commit() public errorCode() public errorInfo() public exec($statement) public getAttribute($attribute) public static getAvailableDrivers() public inTransaction() public lastInsertId($name = NULL) public prepare($statement, array $driver_options = array()) public query($statement) public quote($string, $parameter_type = PDO::PARAM_STR) public rollBack() public setAttribute($attribute, $value) }
Simples
<?php
interface LegCostCalculator { public function calculate($leg); }
Complexa
<?php
interface LegCostCalculator { public function calculateGasCostByDistance($leg); public function calculateTollCost($leg); public function calculateTripdaFee($leg); }
Stateful
<?php
interface File { public function open(); public function read(); public function write(); public function close(); }
Stateless
<?php
interface HttpClient { public function get($url); public function post($url, array $params); }
Herança e composição
–Sandi Metz
“Duplication is far cheaper than the wrong abstraction.”
Com interfaces eu posso criar “papéis”. Combinações de
interfaces que definem uma classe de objetos. De maneira explícita.
<?php
interface ReadableStream { public function read($bytes); }
interface WritableStream { public function write($data); }
interface SeekableStream { public function seek($offset); }
<?php
class FileStream implements ReadableStream, WritableStream, SeekableStream { public function read($bytes); public function write($data); public function seek($offset); }
Considerações finais
Dúvidas?
Fim