Upload
attila-magyar
View
465
Download
1
Embed Size (px)
Citation preview
Gyakori félreértések
Magyar Attila (BalaBit)
PHPMeetup, 2013. április 30.
Bemelegítés: hungarian notation
● sName, arrNodes...
Bemelegítés: hungarian notation
● sName, arrNodes...● m_name, m_Nodes
Bemelegítés: hungarian notation
● sName, arrNodes...● m_name, m_Nodes
Bemelegítés: hungarian notation
class Foo { private $m_name;
public function __construct($name) { $this->m_name = $name; }
public function bar() { for ($i = 0; $i != 3; ++$i) { printf("%s\n", $this->m_name); } }}
Bemelegítés: hungarian notation
class Foo { public: Foo(const char *name) { this->m_name = name; }
void bar() { for (int i = 0; i != 3; ++i) { printf("%s\n", this->m_name); } }
private: const char *m_name;};
Bemelegítés: hungarian notation
class Foo { public: Foo(const char *name) { m_name = name; }
void bar() { for (int i = 0; i != 3; ++i) { printf("%s\n", m_name); } }
private: const char *m_name;};
Bemelegítés: hungarian notation
class Foo { private $m_name;
public function __construct($name) { $this->m_name = $name; }
public function bar() { for ($i = 0; $i != 3; ++$i) { printf("%s\n", $this->m_name); } }}
Bemelegítés: hungarian notation
class Foo { private $m_name;
public function __construct($name) {
$this->m_name = $name; }
public function bar() { for ($i = 0; $i != 3; ++$i) {
printf("%s\n", $this->m_name); } }}
Bemelegítés: hungarian notation
class Foo { private $m_name;
public function __construct($name) {
$this->m_name = $name; }
public function bar() { for ($i = 0; $i != 3; ++$i) {
printf("%s\n", $this->m_name); } }}
Öröklődés
Mi az az OOP?
Öröklődés
Mi az az OOP?● Osztályok, objektumok, metódusok (üzenetek)
Öröklődés
Mi az az OOP?● Osztályok, objektumok, metódusok (üzenetek)● encapsulation, polymorphism, inheritance, dynamic
dispatch
Öröklődés
Mi az az OOP?● Osztályok, objektumok, metódusok (üzenetek)● encapsulation, polymorphism, inheritance, dynamic
dispatch● design patterns, modelling (abstractions)
Öröklődés
Mi az az OOP?● Osztályok, objektumok, metódusok (üzenetek)● encapsulation, polymorphism, inheritance, dynamic
dispatch● design patterns, modelling (abstractions)● REUSABILITY, MAINTAINABILITY
Öröklődés
abstract class Application{ public function run() { $class = get_class($this); syslog(LOG_INFO, "Running $class"); $this->doRun(); }
abstract protected function doRun();}
Öröklődés
class FizzBuzzApplication extends Application{ protected function doRun() { for ($i = 1; $i <= 100; ++$i) { if ($i % 3 == 0) print "Fizz"; if ($i % 5 == 0) print "Buzz"; if ($i % 3 != 0 && $i % 5 != 0) print $i; print "\n"; } }}
Öröklődés
class FizzBuzzApplication extends Application{
protected function doRun() { for ($i = 1; $i <= 100; ++$i) { if ($i % 3 == 0) print "Fizz"; if ($i % 5 == 0) print "Buzz"; if ($i % 3 != 0 && $i % 5 != 0) print $i; print "\n"; } }}
Öröklődés
class FizzBuzzApplication extends Application{ protected function doRun() { for ($i = 1; $i <= 100; ++$i) { if ($i % 3 == 0) print "Fizz"; if ($i % 5 == 0) print "Buzz"; if ($i % 3 != 0 && $i % 5 != 0) print $i; print "\n"; } }}
Öröklődés
class FizzBuzzWebApplication extends FizzBuzzApplication{ protected function doRun() { print "<html><body><pre>"; parent::doRun(); print "</pre></body></html>"; }}
Öröklődés
abstract class Application{ public function run() { $class = get_class($this); syslog(LOG_INFO, "Running $class"); $this->doRun(); }
abstract protected function doRun();}
Öröklődés
abstract class Application{ public function run() { $class = get_class($this); syslog(LOG_INFO, "Running $class"); if (in_array("--help", $GLOBALS["argv"])) { print "Help text\n"; } else { $this->doRun(); } }
abstract protected function doRun();}
Öröklődés
class FizzBuzzWebApplication extends FizzBuzzApplication{ protected function doRun() { print "<html><body><pre>"; parent::doRun(); print "</pre></body></html>"; }}
Notice: Undefined index: argv in...
Öröklődés
class FizzBuzzWebApplication extends FizzBuzzApplication{ protected function doRun() { print "<html><body><pre>"; parent::doRun(); print "</pre></body></html>"; }}
Notice: Undefined index: argv in...
Öröklődés
abstract class DaemonApplication extends Application{ public function run() { $this->updatePidFile(); $this->closeStandardIO(); parent::run(); $this->clearPidFile(); }
/* ... */}
Öröklődés
abstract class SingletonApplication extends Application{ public function run() { if ($this->isRunningAlready()) { throw new Exception("..."); } parent::run(); }
/* ... */}
Öröklődés
abstract class SingletonDaemonApplication
extends ???{ public function run() { /* ... */ }}
Öröklődés
abstract class SingletonDaemonApplication
extends ???{ public function run() { /* ... */ }}
Többszörös öröklődés?
Szerencsére PHP-ben nincs...
Többszörös öröklődés?
Szerencsére PHP-ben nincs... Honnan jönne a run() metódus?
Off: többszörös öröklődés
Deadly diamond of death
Off: többszörös öröklődés
Deadly diamond of death
Off: többszörös öröklődés
Deadly diamond of death
Megoldás?
abstract class SingletonDaemonApplication
extends ???{ public function run() { /* ... */ }}
Megoldás
interface Application{ /** * @brief Entry point for business logic. * @return void */ public function run();
/** * @brief Human-readable name of the application * @return string */ public function getName();}
Megoldás
class ApplicationDecorator implements Application{ private $application;
public function __construct(Application $app) { $this->application = $app; }
public function run() { $this->application->run(); }
public function getName() { return $this->application->getName(); }}
Megoldás
class CommandLineApplication extends ApplicationDecorator{ public function run() { $name = $this->getName(); syslog(LOG_INFO, "Running $name"); if (in_array("--help", $GLOBALS["argv"])) { print "Help text\n"; } else { parent::run(); } }}
Megoldás
class DaemonApplication extends ApplicationDecorator{ public function run() { $this->updatePidFile(); $this->closeStandardIO(); parent::run(); $this->clearPidFile(); }
/* ... */}
Megoldás
class SingletonApplication extends ApplicationDecorator{ public function run() { if ($this->isRunningAlready()) { throw new Exception("Already running"); } parent::run(); }
/* ... */}
Megoldás
new SingletonApplication( new DaemonApplication( new CommandLineApplication( new ConcreteApplication() ) ));
new WebApplication(new ConcreteApplication());
Megoldás
new SingletonApplication( new DaemonApplication( new CommandLineApplication( new ConcreteApplication() ) ));
new WebApplication(new ConcreteApplication());
Hány unit tesztet írjak?
Hány unit tesztet írjak?
1 osztály ↔ 1 unit teszt?
Hány unit tesztet írjak?
1 osztály ↔ 1 unit teszt? 1 metódus ↔ 1 unit teszt?
Hány unit tesztet írjak?
1 osztály ↔ 1 unit teszt? 1 metódus ↔ 1 unit teszt? 1 ??? ↔ 1 unit teszt?
Hány unit tesztet írjak?
Miért írunk unit teszteket egyáltalán?● gyors&mebízható (!!!) feedback (pl. refactoring)● design● élő dokumentáció, példakód
Hány unit tesztet írjak?
Miért írunk unit teszteket egyáltalán?● gyors&mebízható (!!!) feedback (pl. refactoring)● design● élő dokumentáció, példakód
Ha ezeket a célokat eléri, akkor unit teszt
Hány unit tesztet írjak?
Miért írunk unit teszteket egyáltalán?● gyors&mebízható (!!!) feedback (pl. refactoring)● design● élő dokumentáció, példakód
Ha ezeket a célokat eléri, akkor unit teszt Tehát 1 osztályhoz akkor mennyi unit teszt
kell? 1 tesztből hány osztályt szabad/kell használni?
Hány unit tesztet írjak?
Hány unit tesztet írjak?
Hány unit tesztet írjak?
Miért írunk unit teszteket egyáltalán?● gyors&mebízható (!!!) feedback (pl. refactoring)● design● élő dokumentáció, példakód
Ha ezeket a célokat eléri, akkor unit teszt Annyi teszt legyen, amennyi a céljainkhoz elég
Tehát?
A cél a legfontosabb, ne vesszünk el a policy-k, eszközök és szabályok erdejében.
?
FYI: http://www.balabit.com/hu/openacademy (május 23, 17:00, BME Q épület)
http://en.wikipedia.org/wiki/Composition_over_inheritance
Köszönöm a figyelmet