Objects, Testing, and Responsibility
Upcoming SlideShare
Loading in...5
×
 

Objects, Testing, and Responsibility

on

  • 3,512 views

Talk from Laracon EU on August 31, 2013. Style issues due to reveal.js output.

Talk from Laracon EU on August 31, 2013. Style issues due to reveal.js output.

Statistics

Views

Total Views
3,512
Views on SlideShare
3,343
Embed Views
169

Actions

Likes
8
Downloads
37
Comments
0

5 Embeds 169

https://twitter.com 118
http://storify.com 32
http://librosweb.es 14
http://www.google.com 4
http://www.conferize.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Objects, Testing, and Responsibility Objects, Testing, and Responsibility Presentation Transcript

  • OBJECTS, TESTING, AND RESPONSIBILITY MATTHEW MACHUGA LARACON EU AUGUST 2013
  • HI, I'M MATT MACHUGA! SOFTWARE DEVELOPER RUBY | JS | PHP
  • ONLINE: MACHUGA IRC: machuga GitHub: machuga Twitter: @machuga I WEAR MANY HATS IN IRC "Have you checked the docs first?"
  • MORE MACHUGA'S HALI AND VAEDA VIM
  • THINK THROUGH LEARNING THINK THROUGH MATH HELP KIDS LEARN MATH SENIOR SOFTWARE DEVELOPER I HAVE THE BEST COWORKERS EVER!
  • BEFORE WE BEGIN... LARAVEL COMMUNITY!THANK YOU, YOU'RE ALL AMAZING!
  • OBJECTS, TESTING, AND RESPONSIBILITYWAT
  • OBJECTS Object Oriented Programming Object Oriented Design Pro's and Con's Improvements to code
  • TESTING Correlation between good OOD and good tests Tests are good No, seriously. Tests are good. Stop hating.
  • RESPONSIBILITY See also: Accountability Holding components accountable Giving objects explicit responsibilities 1:1 Object:Responsibility Ratio (when possible) Responsibilty to code Responsibilty to team Responsibilty to your future self
  • OBJECTS
  • Alan Kay Father of OOP "I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages"
  • OBJECT-ORIENTED PROGRAMMING Originated from Functional and Procedural Solution to code organization, data-hiding, reuse Solution to easier testing Solution to structure and protocols
  • PHP'S OOP HISTORY
  • QUESTION Which version of PHP first gained objects? PHP 3
  • OOP: OBJECT ORIENTED PHP THE LIVE ACTION SERIES
  • OOP: OBJECT ORIENTED PHP 16 years and 4 days ago: PHP codebase gets classes PHP 3 released in 1998 Associative Array ++
  • OOP: OBJECT ORIENTED PHP PHP 3 & 4 CAPABILITIES Classes Objects Simple single inheritance Pass-by-value All public visibility
  • OOP: OBJECT ORIENTED PHP PHP 5.0 - 5.2.X ENHANCEMENTS Pass-by-reference public/ private/ protectedvisibility Static methods/properties Class constants __construct() Destructors Abstract and Final classes Interfaces
  • OOP: OBJECT ORIENTED PHP PHP 5.3 ENHANCEMENTS Usable single inheritance! Late Static Binding Namespaces Closures
  • OOP: OBJECT ORIENTED PHP PHP 5.3 ANTIPATTERNS goto No full namespace import
  • OOP: OBJECT ORIENTED PHP PHP 5.4 ENHANCEMENTS Traits Closure Rebinding
  • IT TOOK ABOUT 14 YEARS But we now have a very capable object model in PHP
  • THE FOUR PILLARS OF OOP
  • ABSTRACTION Remove and isolate related behavior or data Responsibility
  • EXAMPLES
  • PROCEDURAL <?php function get_db() { /* return the db conneciton */} function user_show($user) { /* Awesome procedural code */ } function user_fetch($user) { $db = get_db(); /* Awesome procedural code */ function user_delete($user) { $db = get_db(); /* Awesome procedural code */ function user_create($user, $data) { $db = get_db(); /* Awesome procedural co function user_update($user, $data) { $db = get_db(); /* Awesome procedural co function user_store_data($user, $user_data) { if (user_fetch($user)) { return user_update($user, $user_data); } else { return user_create($user, $user_data); }
  • ABSTRACTED <php class User extends Eloquent { // All provided by Eloquent public static function find($id) {} public function delete() {} public function create($attributes) {} public function update($attributes) {} public function save() {} }
  • ENCAPSULATION Keep data and behavior in a black box Use a public interface to interact with the black box Much like a function - data in, data out Prevents leaky abstractions
  • EXAMPLE...KIND OF
  • ILLUMINATEDATABASEELOQUENTMODEL PROPERTIES 4 Public Instance/Class 19 Protected Instance/Class 0 Private Instance/Class METHODS 126 Public Instance/Class 25 Protected Instance/Class 0 Private Instance/Class
  • INHERITANCE The double edged sword Allows classes to be extended from other classes Properties and methods can ascend the ancestry Saves a lot of code
  • EXAMPLE - PLAIN CLASSES <?php class Rectangle { public function __construct($coords) {} public function getCoordinates() {} public function setCoordinates($coords) {} public function getXX() {} public function getXY() {} public function getYX() {} public function getYY() {} public function setXX($coord) {} public function setXY($coord) {} public function setYX($coord) {} public function setYY($coord) {}
  • EXAMPLE - INHERITED <?php class Square extends Rectangle {} class Diamond extends Rectangle {} class Rectangle { public function __construct($coords) {} public function getCoordinates() {} public function setCoordinates($coords) {} public function getXX() {} public function getXY() {} public function getYX() {} public function getYY() {} public function setXX($coord) {}
  • POLYMORPHISM Probably the best feature of OOP Any object may be used if it implements expected method/property Allows code branching without if/else logic PHP is a duck typed language - "If it walks like a duck" PHP also allows type hinting - "You will be a duck and you will like it!"
  • EXAMPLE <php class BlogPostWidget { public function render() {} } class GalleryWidget { public function render() {} } class PollWidget { public function render() {} }
  • EXAMPLE W/ TYPE HINTING <php interface Widget { public function render() {} } class BlogPostWidget implements Widget { public function render() {} } class GalleryWidget implements Widget { public function render() {} } class PollWidget implements Widget
  • HOW IS THIS USABLE? Phill Sparks and Fabien showed you yesterday! Pay attention!
  • DESIGN PATTERNS Finding common patterns in code and making it reusable Take advantage of OO constructs
  • CODE REUSE AND EXTENSIBILITY Proper abstraction leads to reusable code Fluent Class in Laravel 3 as an example (not the DB one) Validators in Laravel Drivers
  • LATE-STATIC BINDING selfnever worked like it should've staticis what selfwanted to be selfwill call the class the method was defined on, not the subclass you likely expecting statichowever will
  • EXAMPLE <php class A { public function sadface() { return new self(); } public function happyface() { return new static(); } } class B extends A {} $b = new B(); $b->sadface(); // A object
  • TRAITS Traits allow for methods/properties to be added to a class at compile-time Not quite mixins, but close In a sense, allows for multiple inheritance This scares people Not always the right solution, but often suited Another great form of reusable abstraction
  • EXAMPLE <php trait Bar { protected $baz; public function baz() { return $this->baz; } } class Foo { use Bar; public function setBaz($baz) {
  • GET THE MOST OUT OF YOUR OBJECTS
  • TELL, DON'T ASK Tell your objects what you want them to do Don't ask them data about themselves. Remember: Black box
  • COMPOSITION OVER INHERITANCE Composing two or more objects together The sum is greater than the parts Provides more flexibility Not always the right solution, but often the better suited More code to compose (usually) "Does X belong on this object?"
  • COMPOSITION WITH TRAITS SOME PEOPLE REALLY HATE TRAITS Traits allow for methods/properties to be added to a class at compile-time Not quite mixins, but close In a sense, allows for multiple inheritance This scares people Not always the right solution, but often the better suited Another great form of reusable abstraction
  • TESTING
  • TESTING CAN BE HARD ESPECIALLY IF YOU'RE MAKING IT HARD
  • TDD SERVES MANY PURPOSES Guiding you to make well abstracted solutions Help you write the least code possible Ensure your code works Ensure your code works as it is intended Ensure tests become executable documentation for your code and acceptance criteria
  • TDD CYCLE Red Green Refactor
  • FULL TDD CYCLE Red Red Green Refactor Green Refactor
  • BASE TESTS OFF ACCEPTANCE CRITERIA Stakeholders want their features You want the features to work You want to guarantee your unit tests come together
  • TDD IS NOT THE ONLY WAY Tests don't need to drive or guide your code Testing after is perfectly reasonable BUT ALWAYS LISTEN TO YOUR TESTS
  • LISTENING TO TESTS Tests will let you know if somethign smells funny A class that does too many things is hard to test A test with too many dependencies is hard to test A test with too many mocks is hard to mantain A test that is too difficult is easy to abandon
  • DON'T BE AFRAID TO ADD MORE OBJECTS/CLASSES
  • EXAMPLE - AUTHORITY <php protected $dispatcher; public function __construct($currentUser, $dispatcher = null) { $this->rules = new RuleRepository; $this->setDispatcher($dispatcher); $this->setCurrentUser($currentUser); $this->dispatch('authority.initialized', array( 'user' => $this->getCurrentUser(), )); } public function dispatch($eventName, $payload = array()) { if ($this->dispatcher) { return $this->dispatcher->fire($eventName, $payload);
  • EXAMPLE - AUTHORITY TESTS <php public function testInitializeEvent() { $test = new stdClass; $user = new stdClass; $user->name = 'Tester'; $this->dispatcher->listen('authority.initialized', function($payload $test->user = $payload->user; $test->timestamp = $payload->timestamp; }); $authority = new Authority($user, $this->dispatcher); $this->assertSame($test->user, $user); $this->assertInstanceOf('DateTime', $test->timestamp); }
  • SOME THINGS ON TESTING You do not need a test for every method Sometimes you need more than one test for a method Mocking can fall short and lose sync. If you don't test everything, test areas of high churn Do not reach for AspectMock right away because something is hard Test your own code, not third party
  • SOME MORE THINGS ON TESTING This is not a good test <php testFoo() { $foo = new Foo(); $bar = new Bar(); $baz = $foo->doSomethingEpic($bar); if (is_array($baz) and !is_empty($baz)) { $this->assertTrue(true); } else { $this->assertFalse(true); } }
  • SOME MORE THINGS ON TESTING Nor this <php testSomething() { $foo = new Foo(); $bar = new Bar(); $baz = $foo->doSomethingEpic($bar); // Baz doesn't seem to eval right, passing for now // @TODO: Come back later $this->assertTrue(true); }
  • SOME MORE THINGS ON TESTING Nor this <php testStringReverse() { $str = new AwesomeString(); $string = 'Hello'; // Implementation: return strrev($string) $reversed = $str->reverseString($string); $this->assertEquals(strrev($string), $reversed); }
  • SOME MORE THINGS ON TESTING Nor this...I don't even... <php testWeirdFeature() { // 2 + 2 should be 4 if (2+2 == 3) { $this->assertTrue(true); } else { $this->assertTrue(false); } }
  • CAN IT BE CLEANED UP? ABSOLUTELY! BUT IT WORKS!
  • RESPONSIBILITY
  • RESPONSIBILITY You have a responsibility not to make tests like what I've just shown
  • RESPONSIBILITY: OBJECTS Give your objects a task Do not overwork your objects Give your objects some proper tests Like profiling and logging, objects can help with accountability
  • RESPONSIBILITY: YOU You have a responsibility to yourself You have a responsibility to your team You have a responsibility to your consumers You have a responsibility to your future self Become responsible and be accountable for your code
  • QUESTIONS?
  • THANK YOU! IRC: machuga GitHub: machuga Twitter: @machuga