• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Dutch PHP Conference 2013: Distilled
 

Dutch PHP Conference 2013: Distilled

on

  • 1,436 views

A couple of our team members attended DPC13, and this is a subset of some of the interesting talks we wanted to share with the rest of the team.

A couple of our team members attended DPC13, and this is a subset of some of the interesting talks we wanted to share with the rest of the team.

Statistics

Views

Total Views
1,436
Views on SlideShare
1,436
Embed Views
0

Actions

Likes
0
Downloads
3
Comments
0

0 Embeds 0

No embeds

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

    Dutch PHP Conference 2013: Distilled Dutch PHP Conference 2013: Distilled Presentation Transcript

    • Dutch PHP Conference: Distilled Chris Saylor Stephen Young @cjsaylor @young_steveo
    • Focus of this talk PHP by the Numbers Emergent Design What's new in PHP 5.5 Unbreakable Domain Models
    • PHP by the Numbers
    • Measuring Complexity Cyclomatic complexity N-path complexity
    • Cyclomatic complexity The cyclomatic complexity of a method is the count of the number of independent decision points in the method, plus one for the method entry.
    • It's a fancy term for measuring the complexity of a method. Decision points in a method increase complexity. (e.g. if, else, foreach, etc.) Plugins will calculate it for you. (PHP Mess Detector, JSHint, Grunt!)
    • The lower, the better 1—4 low complexity, easy to maintain 5—7 moderate complexity 8—10 high complexity, hard to test 11+ ?
    • N-path complexity The number of acyclic execution paths through a function; an objective measure of complexity related to the ease with which software can be comprehensively tested
    • acyclic execution paths?
    • It's a lot like cyclomatic complexity. It measures how many straight lines you can draw through a method. A method with a single IFstatement has an N-path of 2. A method with 2 IFstatements has an N-path of 4. 3 IFstatements would make the N-path 8.
    • Another way to look at it The value of a method's N-path complexity is equal to the number of unit tests needed to ensure that you have 100% code coverage. A "quick estimate" for N-Path: 2^(cyclomaticComplexity - 1)
    • You have probably seen this Running Grunt! Running "jshint:source" (jshint) task Linting app/webroot/js/views/doesEverythingView.js... ERROR [L31:C38] W074: This function's cyclomatic complexity is too high. (18)
    • Things to avoid Violating the Single Responsibility Principle A Controller method with logic to perform CRUD operations. A Product Model with logic for formatting currency. Seperation of Concerns Too complex: A single method that executes four business rules to perform a task. Better: Four methods that each execute a single business rule.
    • Plan Ahead It's common to be handed a user story that is simple to describe but complex to implement. Take time to break the logic into the smallest possible units before writing code.
    • Emergent Design with PHPSpec
    • Topics covered 1. PHPSpec overview 2. emergent design 3. simple design & smells 4. designing composition with mocks
    • What is PHPSpec?
    • it started as a port for rspec
    • Problem PHP !== Ruby
    • in ruby everything is an object and all objects are open Also, monkey patching code at runtime is a typical practice in the Ruby world. blowling.score.should eq(0)
    • an early PHPSpec syntax example Trying to emulate ruby in PHP looks ugly $this->spec($bowling->getScore())->shouldEqual(0);
    • PHPSpec's new goals fun to work with development tool let's not get in the way enforce TDD do it the PHP way
    • Test Driven Development yellow — Write the test first red — Implement the class/method; test is failing green — Test is passing
    • How PHPUnit handles the Yellow step PHPUnit 3.7.14 by Sebastian Bergmann. PHP Fatal error: Class 'Markdown' not found in /Users/stephenyoung/Documents/projects/Lab/phpuni t/tests/MarkdownTest.php on line 8 Fatal error: Class 'Markdown' not found in /Users/stephenyoung/Documents/projects/Lab/phpunit/te sts/MarkdownTest.php on line 8
    • How PHPSpec handles the Yellow step it does this for missing methods too. > specCustomer ✘ it converts plain text to html paragraphs Class Markdown does not exist. Do you want me to create it for you? [Y/n]
    • Mocking It suffices to say that mocking is painful in PHPUnit. PHPSpec has a very easy-to-use Mocking library. Too much to go into here.
    • That's Enough about PHPSpec It's a pretty awesome tool. Go check it out.
    • Emergent Design
    • What is software design?
    • Software design is the art of describing how to to solve a problem.
    • First learn design, then learn emergent design
    • Alan Kay on Messaging "The key in making great and growable systems is much more to design how its modules communicate rather than what their internal properties and behaviors should be."
    • $this->person->getCar()->getEngine()->ignite();
    • Focusing on messaging makes code more flexible
    • $this->person->startCar();
    • Software design is the art of describing how to to solve problems with roles, responsibilities and messages
    • Big Design Up Front It's hard to change later. We need to think about things before developing. We need to make sure we don't miss anything. This is just the way we do it.
    • Y A G N I
    • 61% of all requested features are actually delivered
    • 27% of all requested features are actually used
    • 5% to 10% are responsible for realising the envisioned benefits
    • we should design for the high priority items and make it easy to change later.
    • Agile Software design is the art of describing how to to solve problems with roles, responsibilities and messages in a change-friendly way
    • Easier said than done?
    • 1. Test 2. Code 3. Refactor 4. Repeat
    • Use simple design rules to refactor 1. All tests run and pass 2. Remove duplication 3. Remove opacity 4. Remove complexity
    • What is the result of this method in your code? It is testable. It is modular. It is expressive. It is simple.
    • What is the alternative? Viscosity Immobility, Rigidity, Fragility Unreadable Complex
    • Simple design enables smell detection
    • Simple Design 1. All tests run and pass 2. Remove duplication 3. Remove opacity 4. Remove complexity smells 1. Test smells? 2. DRY smells? 3. Opacity smells? 4. Complexity smells?
    • Test smells Lack of tests Setup is too complex Unclear exercise No expectation
    • DRY Smells Copy Pasta Logic duplication Duplicated constants Alternative classes with different interfaces
    • Opacity smells Naming not in the domain Name does not express intent Feature envy Method too long Method does more than one thing
    • Complexity smells Unnecessary else Unnecessary if Unnecessary switch Too many passed arguments
    • Use design patterns to refactor
    • What can happen in a method? return a value throw an exception delegate modify state not the final behavior print something we should probably delegate that too
    • Design delegation with mocks
    • start by defining behavior
    • internally delegate to another method
    • Finally Define new role Extract collaborators using mocks Move behavior definition to new collaborator test
    • What's new in PHP 5.5
    • Performance Performance boost compared to 5.3 -> 5.4 is not as great as 5.4 -> 5.5
    • APC replacement Zend's OPCache is now packaged with PHP 5.5 and APC is now depricated
    • array_column $keyValues = [ ['key1' => 'val1', 'key2' => 'val2'], ['key1' => 'val3', 'key2' => 'val4'] ]; var_dump(array_column($keyValues, 'key1')); // yields array('val1', 'val3')
    • Foreach with list $test = [ [1, 2], [3, 4] ]; foreach ($test as list($a, $b)) { echo "a: $a; b: $b"; } // displays: // a: 1; b: 2 // a: 3; b: 4
    • Finally a finally! try { doSomeWork(); return true; } finally { cleanUpSomeStuff(); echo "I am reachable!"; } echo "I am not reachable :( ";
    • Generators function lotsOfRecords() { while ($row = $this->db->getNext()) { yield $row['id'] => $row; } } foreach (lotsOfRecords() as $id => $row) { // do stuff }
    • Password hashing API echo password_hash('somepassword', PASSWORD_BCRYPT); // $2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K password_verify( 'somepassword', '$2y$12$QjSH496pcT5CEbzjD/vtVeH03tfHKFy36d4J0Ltp3lRtee9HDxY3K' ); // true
    • Unbreakable Domain Models
    • Use objects as consistency boundaries class Customer { public function __construct($email) { if( /* ugly regex here */) { throw new InvalidArgumentException(); } $this->email = $email; } }
    • Single Responsibility Principle class Email { private $email; public function __construct($email) { if( /* ugly regex here */) { throw new InvalidArgumentException(); } $this->email = $email; } public function __toString() { return $this->email; } }
    • Customer class is now tighter class Customer { /** @var Email */ private $email; public function __construct(Email $email) { $this->email = $email; } }
    • Encapsulate state and behavior with Value Objects
    • A user story may be: "A customer orders products and pays for them."
    • Procedural $order = new Order; $order->setCustomer($customer); $order->setProducts($products); $order->setStatus(Order::UNPAID); // ... $order->setPaidAmount(500); $order->setPaidCurrency(‘EUR’); $order->setStatus(Order::PAID);
    • Improve it with object for consistency $order = new Order; $order->setCustomer($customer); $order->setProducts($products); $order->setStatus( new PaymentStatus(PaymentStatus::UNPAID) ); $order->setPaidAmount(500); $order->setPaidCurrency(‘EUR’); $order->setStatus( new PaymentStatus(PaymentStatus::PAID) );
    • Improve it with more consistency $order = new Order; $order->setCustomer($customer); $order->setProducts($products); $order->setStatus( new PaymentStatus(PaymentStatus::UNPAID) ); $order->setPaidMonetary( new Money(500, new Currency(‘EUR’)) ); $order->setStatus( new PaymentStatus(PaymentStatus::PAID) );
    • Even more $order = new Order($customer, $products); // set PaymentStatus in Order::__construct() $order->setPaidMonetary( new Money(500, new Currency(‘EUR’)) ); $order->setStatus( new PaymentStatus(PaymentStatus::PAID) );
    • Getting ridiculous now $order = new Order($customer, $products); $order->pay( new Money(500, new Currency(‘EUR’)) ); // set PaymentStatus in Order#pay()
    • Encapsulation through specification "I want to give a discount to a customer that has at least 3 orders." interface CustomerSpecification { /** @return bool */ public function isSatisfiedBy(Customer $customer); }
    • class CustomerIsPremium implements CustomerSpecification { private $orderRepository; public function __construct( OrderRepository $orderRepository ) {...} /** @return bool */ public function isSatisfiedBy(Customer $customer) { $count = $this->orderRepository->countFor($customer); return $count >= 3; } } $customerIsPremium = new CustomerIsPremium($orderRepository) if($customerIsPremium->isSatisfiedBy($customer)) { // send special offer }
    • Credits PHP By the numbers - Anthony Ferrara Emergent Design with phpspec - Marcello Duarte Unbreakable Domain Models - Mathias Verraes Let's have a look at PHP 5.5 - Julien Pauli