Seven Steps to Better OOP Code

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

1 comments

Comments 1 - 1 of 1 previous next Post a comment

  • + afilina Anna Filina 6 months ago
    This was my favorite presentation, even though I was familiar with the concepts. I guess I just love OOP and elegant code that much.
Post a comment
Embed Video
Edit your comment Cancel

19 Favorites, 1 Group & 1 Event

Seven Steps to Better OOP Code - Presentation Transcript

  1. Seven Steps to Better OOP Code Stefan Priebsch, thePHP.cc php|tek 09, Chicago, IL, U.S.A.
  2. Stefan Priebsch Co-Founder and Principal Consultant
  3.  
  4. Disclaimer
  5. „ Hang the rules. They're more like guidelines anyway.“ --Elizabeth Swann, Pirates of the Caribbean
  6. Is OOP slow?
    • The usual disclaimer for benchmarks applies!
    foo() 3.09 µsec Test::foo() 3.26 µsec $test->foo() 3.12 µsec $test = new Test(); $test->foo() 4.03 µsec
  7. Wow, 25% slower!
  8. Let us put 1 µsec into perspective
    • The usual disclaimer for benchmarks applies!
    print ~ 10 µsec file_get_contents() ~ 30 µsec mysql_connect() ~ 100 µsec HTTP GET Request ~ 35,000 µsec
  9. Do not care about performance *
      *Some restrictions may apply.
    #1
  10. Use objects
  11. Use more objects
    • class Something { protected $status = array(); public function run(...) { if (...) { … $this->status['fail'] = $e->getMessage(); } else { $this->status['skip'] = 'File is unavailable'; } return $this->status; } }
    • class Something { protected $status = array(); public function run(...) { if (...) { … return new FailResult($e->getMessage()); } else { return new SkipResult('File is unavailable'); } } }
    • class Result { protected $message; public function __construct($message) { $this->message = $message; } } class FailResult extends Result {} class SkipResult extends Result {}
  12. What do you do for a living?
    • class Something { public function doManyThings() { … load data … … perform calculations … … render HTML output … … store calculation result ... } }
    • class Something { public function doManyThings() { $this->loadData(); $this->performCalculations(); $this->renderHtml(); $this->storeResult(); } protected function loadData() protected function performCalulations() protected function renderHtml() protected function storeResult() }
    • class DataLoader { public function loadData() } class Calculator { public function calculateResult() } class HtmlRenderer { public function render() } class StorageManager { public function storeResult() }
  13. One class One responsibility
    • class DomainObject { protected function loadData() { $this->data = $this->db->query(...); } public function render() { $this->loadData(); return HtmlRenderer::createTable($this->data); } }
  14. Let others do the work
    • class DomainObject { protected function loadData() { $this->data = $this->dataManager->query(...); } public function render() { $this->loadData(); $this->dataRenderer->renderTable($this->data); } }
  15. Keep your secrets
    • class SomeDomainObject { public function doSomething($a, $b, $c) { … return new SomeResult($x, $y, $z); } }
  16. Keep objects dumb
    • class SomeDataProcessor { public function process($filename) { … $data = file_get_contents($filename); … } }
    • class SomeDataProcessor { public function process($data) { … } }
  17. Do not talk to strangers
    • class MeMySelfAndI { protected function talk() { Stranger::askForACigarette(); } }
    • class MeMySelfAndI { protected function talk() { Stranger::getInstance()->askForACigarette(); } }
    • class MeMySelfAndI { protected function talkTo($friend) { $friend->askForACigarette(); } } class Friend { public function askForACigarette() { return new Cigarette(); } }
  18. Create loosely coupled classes #3
  19. Which tools do you need to do your job?
    • class DomainObject { protected function loadData() { $this->data = $this->dataManager->query(...); } public function render() { $this->loadData(); $this->dataRenderer->renderTable($this->data); } }
    • class DomainObject { protected $dataManager; protected $dataRenderer; public function __construct($dataManager, $dataRenderer) { $this->dataManager = $dataManager; $this->dataRenderer = $dataRenderer; } protected function loadData() public function render() }
  20. Use dependency injection #4
  21. fuel injection a means of metering fuel into an internal combustion engine
    • class Car { protected $engine; protected $wheels = array(); public function __construct() { $this->engine = new Engine(); $this->wheels = array( new Wheel(), new Wheel(), new Wheel(), new Wheel(), ); } }
    • class Car { protected $engine; protected $wheels = array(); public function __construct($engine, array $wheels) { $this->engine = $engine; $this->wheels = $wheels; } }
    • class Car { protected $engine; protected $wheels = array(); public function __construct(Engine $engine, array $wheels) { $this->engine = $engine; $this->wheels = $wheels; } }
    • class Car { protected $engine; protected $wheels = array(); public function __construct(Engine $engine) { $this->engine = $engine; } public function addWheel(Wheel $wheel) { $this->wheels[] = $wheel; } }
    • class Car { protected $engine; protected $wheels = array(); public function __construct(Engine $engine) { $this->engine = $engine; } public function addWheel(Wheel $wheel) { $this->wheels[] = $wheel; } }
  22. Composition over inheritance #5
  23. You can always extend good OOP code
  24. Solve the problem, do not generalize #6
  25. Try test-driven development #7
  26. If it's not tested, it does not exist
  27. Test-Driven Development
    • Write a (unit) test first
    • Make sure it fails
    • Write code to make the test pass
    • Start over again
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function test() { } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function test...() { } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testSomething() { } }
  28. Focus on the API
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } }
  29. I don't know what an ElePHPant is, idiot!
    • class ElePHPant { protected $color = '#009'; public function getColor() { return $this->color; } }
  30. Congratulations, you've just created a blue ElePHPant!
    • class ElePHPant { protected $color = '#008'; public function getColor() { return $this->color; } }
  31. No, this ElePHPant is not blue any more!
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } public function testAnElePHPantHasPhpLogo() { $e = new ElePHPant(); $this->assertTrue($e->getLogo() instanceOf Logo); } }
    • class ElePHPant { protected $color = '#009'; public function getColor() { return $this->color; } public function getLogo() { return $this->logo; } }
  32. No, there is no logo on that ElePHPant!
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } public function testAnElePHPantHasPhpLogo() { $e = new ElePHPant(); $this->assertTrue($e->getLogo() instanceOf Logo); } }
    • class ElePHPant { protected $color = '#009'; protected $logo; public function __construct(Logo $logo) { $this->logo = $logo; } public function getColor() { return $this->color; } public function getLogo() { return $this->logo; } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } public function testAnElePHPantHasPhpLogo() { $e = new ElePHPant(); $this->assertTrue($e->getLogo() instanceOf Logo); } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } public function testAnElePHPantHasPhpLogo() { $e = new ElePHPant(new Logo()); $this->assertTrue($e->getLogo() instanceOf Logo); } }
    • require 'PHPUnit/Framework.php'; class TryingTddTest extends PHPUnit_Framework_TestCase { public function testAnElePHPantIsBlue() { $e = new ElePHPant(); $this->assertEquals('#009', $e->getColor()); } public function testAnElePHPantHasPhpLogo() { $e = new ElePHPant(new Logo()); $this->assertTrue($e->getLogo() instanceOf Logo); $this->assertEquals('PHP', $e->getLogo()->getText()); } }
    • class Logo { protected $text; public function __construct($text) { $this->text = $text; } }
  33. … and they kept coding happily ever after ...
  34.  
  35.  
  36. http://thephp.cc Twitter: thephpcc [email_address] http://www.priebsch.de Twitter: spriebsch Xing, LinkedIn, Facebook
  37.  

+ Stefan PriebschStefan Priebsch, 6 months ago

custom

3612 views, 19 favs, 4 embeds more stats

You have a basic OOP knowledge in PHP? You have see more

More info about this document

© All Rights Reserved

Go to text version

  • Total Views 3612
    • 2932 on SlideShare
    • 680 from embeds
  • Comments 1
  • Favorites 19
  • Downloads 210
Most viewed embeds
  • 674 views on http://www.priebsch.de
  • 3 views on http://www.iweb34.com
  • 2 views on http://blog.phpquiz.net
  • 1 views on http://www.limespace.de

more

All embeds
  • 674 views on http://www.priebsch.de
  • 3 views on http://www.iweb34.com
  • 2 views on http://blog.phpquiz.net
  • 1 views on http://www.limespace.de

less

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

Cancel
File a copyright complaint
Having problems? Go to our helpdesk?

Categories

Groups / Events