Milan Herda, 03 / 2018
Príklady sú vlastné alebo prebrané z knihy
Profesia, FatChilli, Porada, BlueOrange, NOV
profesia.sk, domelia.sk, rtvs.sk, reality.sme.sk, living.sk...
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
Zdrojové súbory:
class JurajSiroky
{
// ...
}
interface StatnaZakazka
{
public function vyberDodavatela(
JurajSiroky $dodavatel
);
}
interface DodavatelSplnajuciPodmienky
{
// ...
}
interface StatnaZakazka
{
public function vyberDodavatela(
DodavatelSplnajuciPodmienky $dodavatel
);
}
Nie je to takto lepšie?
class Authentication
{
private ConnectionInterface $connection;
public function __construct(ConnectionInterface $connection)
{
$this->connection = $connection;
}
public function checkCredentials(string $username, string $password)
{
$user = $this->connection->fetchAssoc(
'SELECT * FROM users WHERE username = ?',
[$username]
);
if ($user === null) {
throw new InvalidCredentialsException('User not found');
}
// validate password
// ...
}
}
Potrebuje autentifikácia vedieť, kde sú uložené používateľské dáta?
Je možné mať používateľské dáta uložené inde ako v databáze?
class Authentication
{
private UserProviderInterface $userProvider;
public function __construct(UserProviderInterface $userProvider)
{
$this->userProvider = $userProvider;
}
public function checkCredentials(string $username, string $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
{
// ...
}
Je jednoduchšie vymeniť inštanciu niečoho abstraktného, ako konkrétnu vec
Naprogramujte tzv. FizzBuzz generátor, ktorý:
Upravte váš FizzBuzz generátor:
interface RuleInterface
{
public function matches(int $number): bool;
public function getReplacement(): mixed;
}
class FizzRule implements RuleInterface
{
public function matches(int $number): bool
{
return $number % 3 === 0;
}
public function getReplacement(): mixed
{
return 'Fizz';
}
}
class FizzBuzzGenerator
{
private $rules = [];
public function addRule(RuleInterface $rule)
{
$this->rules[] = $rule;
}
public function generateList(int $limit): array
{
$list = [];
for ($number = 1; $number <= $limit; $number++) {
$list[] = $this->generateElement($number);
}
return $list;
}
private function generateElement(int $number): mixed
{
foreach ($this->rules as $rule) {
if ($rule->matches($number)) {
return $rule->getReplacement();
}
}
return $number;
}
$fizzBuzz = new FizzBuzzGenerator();
$fizzBuzz->addRule(new FizzBuzzRule());
$fizzBuzz->addRule(new FizzRule());
$fizzBuzz->addRule(new BuzzRule());
...
$list = $fizzBuzz->generateList(100);
Riešenie:
Aby bol kód ľahko udržiavateľný, rozširovateľný, testovateľný a rozširovateľný s minimálnym množstvom programovania, tak každá trieda by mala:
Viac informácií:
Matthias Noback - Principles of Package Design