08/2016 / Milan "perún" Herda / @moriquend / prezentacie.perunhq.org
Príklady prebrané z knihy Principles of Package DesignNaprogramujte tzv. FizzBuzz generátor, ktorý:
Skratka predstavujúca 5 základných princípov dobrého softvérového návrhu
Ak váš kód potrebuje k svojej činnosti iný objekt (funkciu/triedu), tak tento objekt je závislosťou pre váš kód.
Najviac viditeľné sú parametre metód a property tried
Je jednoduchšie vymeniť inštanciu niečoho abstraktného ako konkrétnu vec
Ktorý zápis interfacu sa vám zdá správnejší?
// riesenie 1
class Siroky { /* ... */ }
interface StatnaZakazka
{
public function akceptujDodavatela(
Siroky $dodavatel
);
}
// riesenie 2
interface SplnaPodmienkyInterface { /* ... */ }
interface StatnaZakazka
{
public function akceptujDodavatela(SplnaPodmienkyInterface $dodavatel);
}
Upravte váš FizzBuzz generátor:
interface RuleInterface {
public function matches($number);
public function getReplacement();
}
class FizzRule {
public function matches($number) {
return $number % 3 === 0;
}
public function getReplacement() {
return 'Fizz';
}
}
class FizzBuzzGenerator {
private $rules = [];
public function addRule(RuleInterface $rule) {
$this->rules[] = $rule;
}
public function generateList($limit) {
$list = [];
for ($number = 1; $number <= $limit; $number++) {
$list[] = $this->generateElement($number);
}
return $list;
}
private function generateElement($number) {
foreach ($this->rules as $rule) {
if ($rule->matches($number)) {
return $rule->getReplacement();
}
}
return $number;
}
$fizzBuzz = new FizzBuzz();
$fizzBuzz->addRule(new FizzBuzzRule());
$fizzBuzz->addRule(new FizzRule());
$fizzBuzz->addRule(new BuzzRule());
...
$list = $fizzBuzz->generateList(100);
use Doctrine\DBAL\Connection;
class Authentication {
private $connection;
public function __construct(Connection $connection) {
$this->connection = $connection;
}
public function checkCredentials($username, $password) {
$user = $this->connection->fetchAssoc(
'SELECT * FROM users WHERE username = ?',
[$username]
);
if ($user === null) {
throw new InvalidCredentialsException('User not found');
}
// validate password
// ...
}
}
class Authentication {
private $userProvider;
public function __construct(UserProviderInterface $userProvider) {
$this->userProvider = $userProvider;
}
public function checkCredentials($username, $password) {
$user = $this->userProvider->findUser($username);
if ($user === null) {
throw new InvalidCredentialsException('User not found');
}
// validate password
// ...
}
}
interface UserProviderInterface {
public function findUser($username);
}
class DoctrineDbalUserProvider implements UserProviderInterface {
// ...
}
class TextFileUserProvider implements UserProviderInterface {
// ...
}
Aby bol kód ľahko udržiavateľný, rozšíriteľný, testovateľný a rozširovateľný s minimálnym množstvom programovania, tak každá trieda by mala: