• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Best practices tekx
 

Best practices tekx

on

  • 9,321 views

Tutorial delivered by Matthew Weier O'Phinney and Lorna Mitchell at TEK-X in Chicago, May 2010

Tutorial delivered by Matthew Weier O'Phinney and Lorna Mitchell at TEK-X in Chicago, May 2010

Statistics

Views

Total Views
9,321
Views on SlideShare
7,831
Embed Views
1,490

Actions

Likes
8
Downloads
93
Comments
0

6 Embeds 1,490

http://www.lornajane.net 1175
http://www.slideshare.net 293
http://blog.hackix.com 14
https://twitter.com 6
http://beta.lornajane.net 1
http://translate.googleusercontent.com 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

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

    Best practices tekx Best practices tekx Presentation Transcript

    • Best Practices Matthew Weier O'Phinney Zend Framework Lorna Jane Mitchell Ibuildings @lornajane @weierophinney
    • The Plan
      • Source Control
      • Coding Standards
      • Design Patterns
      • Documentation
      • Testing
      • Quality and Continuous Integration
      • Deployment
    • Source Control
    • Source Control Features
      • Version history of all files
      • Collaboration tool
      • Authoritative version of a project
      • Integration point
    • Using Source Control
      • Create a repository, add project
      • Check out project
      • Make changes
      • Update to get other changes
      • Commit changes to repo
    • svn log ------------------------------------------------------------------------ r3 | lornajane | 2010-04-25 10:32:09 +0100 (Sun, 25 Apr 2010) | 1 line adding documentation notes ------------------------------------------------------------------------ r2 | lornajane | 2010-04-22 09:07:56 +0100 (Thu, 22 Apr 2010) | 1 line outlining source control and design patterns sections ------------------------------------------------------------------------ r1 | weierophinney | 2010-03-30 17:37:27 +0100 (Tue, 30 Mar 2010) | 1 line Added readme with outline ------------------------------------------------------------------------
    • svn diff Index: README.txt =================================================================== --- README.txt (revision 3) +++ README.txt (revision 4) @@ -31,12 +35,20 @@ to share ideas to raise profile to be told you're doing it wrong! + (pulling up examples off our own blogs, if connection allows) Testing (Matthew) QA tools and CI including code analysis, mess detection, etc (Lorna - QA tools; Matthew - CI) + Static analysis + code sniffer + demo examples, find a suitable small codebase (joindin?) + mess detector + demo examples + what else? + Deployment
    • Source Control Tools
      • Subversion (svn)
        • http://subversion.apache.org/
      • Git (git)
        • http://git-scm.com/
      • Bazaar (bzr)
        • http://bazaar.canonical.com/
      • Mercurial (hg)
        • http://mercurial.selenic.com/
    • Accessing Source Control
      • IDE Plugins
      • Trac ( http://trac.edgewall.org/ )
      • TortoiseSVN
        • TortoiseGit
        • TortoiseBzr
        • TortoiseHg
    • Centralised Source Control user repo user user user
    • Centralised Source Control
      • Single repo (repository)
      • Always commit to central
      • Can branch centrally
    • Repository Structure (Feature Branches)
    • Repository Structure (Long-Lived Branches)
    • Repository Structure (Release Branches)
    • Distributed Source Control repo repo repo repo repo
    • Distributed Source Control
      • Many repos
      • Commit to local repo
      • Share changes between anywhere
      • No central point
    • The Changing Landscape
      • Very active development area
      • Today's conclusions not valid for long!
    • Bridges
      • git-svn
        • http://www.kernel.org/pub/software/scm/git/docs/git-svn.html
      • bzr-svn
        • https://launchpad.net/bzr-svn
      • Check out from SVN to local repo
      • Make as many changes/branches as you like
      • Push back to SVN
    • Hosted Solutions GitHub http://github.com/ git Bitbucket http://bitbucket.org/ hg Google Code http://code.google.com/ svn, hg Launchpad https://launchpad.net/ bzr SourceForge http://sourceforge.net/ svn, bzr, hg, git (and cvs)
    • What If I Don't Have Source Control?
      • Get some :)
      • Install subversion
      • Use a hosted solution
    • Resources
      • Talks at TEK-X
        • Subversion in a Distributed World, Lorna Mitchell
        • Getting Git, Travis Swicegood (who literally wrote the book)
        • Both Wednesday afternoon
      • Subversion book
        • http://svnbook.red-bean.com/
      • Comparison of tools
        • http://en.wikipedia.org/wiki/Comparison_of_revision_control_software
    • Coding Standards
    • You don't have a standard when …
      • You always reformat code you get from others
      • Code you wrote 6 months ago looks different than what you wrote today
      • Modifying old code often introduces new syntax errors
    • Answer the following questions:
      • Can you read your own code?
      • Can others read your code?
      • Can you read other's code?
      • Can you switch between code bases easily?
    • Analogy "Elements of Style" :: Writing Coding Standard :: Development
    • In sum, coding standards assist in:
      • Maintainability
      • Collaboration
    • How CS aids maintainability: Code is structured predictably
    • How CS aids collaboration
      • Any developer can pick up and easily read existing code
      • … which in turn means they can maintain it
      • … which de-centralizes who is responsible for the code
      • … which means issues and reature requests are resolved faster
      • It democratizes code maintenance
    • Two pillars of a Coding Standard:
      • Consistency of file system layout
      • Consistency of code layout
    • Ancillary goal:
      • Consistency in naming
    • Use Public Standards
      • NIH has no place with CS
        • You and your project's needs are not unique
        • What if you need to consume and potentially help maintain 3rd party libraries?
        • Benefit from collective knowledge and empirical discoveries
    • Need more reasons?
      • Objectivity
        • Choices are no longer based on subjective preferences, but on empirical experience.
      • Requirement when hiring or outsourcing
        • Easily judge the candidate's experience and code quality.
      • Compatibility
        • Use a standard that follows that of the libraries you use.
    • Choices
      • Horde/PEAR/Zend Framework
        • Also: Solar, AdoDB, Doctrine 2, Symfony 2, and more...
      • eZcomponents/ZetaComponents
      • PHPLIB
    • Example <?php /** * In Foo/Bar.php */ class Foo_Bar { const BAZ = 'baz' ; protected $_bat ; public $bas ; public function bazBat( $someVar ) { if ( $someVar ) { echo 'Found' ; } } }
    • Resources
      • PEAR
        • http://pear.php.net/manual/en/standards.php
        • http://pear.php.net/manual/en/pear2cs.php
      • Zend Framework
        • http://framework.zend.com/manual/en/coding-standard.html
    • Design Patterns
    • A Design Pattern Is ...
      • NOT rocket science
      • A common way to describe a common problem
      • Shared language
      • A problem and solution which is repeated many times
      • Common across programming languages
      • Heavily OOP
    • Some Common Patterns
      • Factory
      • Registry
      • Adapter
      • Decorator
      • Observer
    • Factory
      • Has methods to create and return objects
      • May return different objects
      • May use complex (and maintainable) logic to work out what to do
    • Factory Example: Hat Types 1 < ?php 2 3 require_once ( 'hat.php' ); 4 5 class HatFactory { 6 public function getHat ( $type = 'woolly' ) { 7 // perform any logic you like here 8 return new Hat ( $type ); 9 } 10 } http://www.flickr.com/photos/91524358@N00/2260054061/
    • Registry
      • Can be a singleton (but this is not a requirement!)
      • Register objects here, access from elsewhere
      • Often a factory/registry combination
    • Registry Example: Hat Storage 1 < ?php 2 3 class HatRegistry { 4 private $registry ; 5 6 public function __construct () { 7 $this -> registry = array (); 8 } 9 10 public function registerHat ( $key , $hat ) { 11 $this -> registry [ $key ] = $hat ; 12 } 13 14 public function fetchHat ( $key ) { 15 return $this -> registry [ $key ]; 16 } 17 }
    • Adapter
      • Adapts a specific interface to fit something else; typically, to provide a common API to related classes/components that have divergent APIs.
      • Allows the class wrapped by the adapter to exist independently from the component consuming the adapter.
    • Adapter Example: SOAP to REST
      • Real life example
      • Client project to deliver SOAP
    • PHP SOAP 1 < ?php 2 3 require_once ( 'lib/myClass.php' ); 4 5 $server = new SoapServer ( null , $options ); 6 $server -> setClass ( &quot;MyClass&quot; ); 7 $server -> handle ();
    • Adapter Example: SOAP to REST
      • Real life example
      • Client project to deliver SOAP
      • Service part-built
      • Client reads textbook(?)
      • Client requests REST
      • Adapter class to the rescue!
    • Adapter Example: SOAP to REST myClass index.php
    • Adapter Example: SOAP to REST myClass index.php Adapter
    • Decorator
      • Wraps another class in order to modify its behavior
      • Target class doesn't change
      • Decorating class often implements the same interface(s)
      • Can be visually decorative, not always
    • Decorator Example 1 < ?php 2 3 interface LabelInterface { 4 public function render (); 5 } 6 7 class BasicLabel implements LabelInterface { 8 public function render () { 9 return $this -> label ; 10 } 11 }
    • Decorator Example 13 abstract class LabelDecorator implements LabelInterface { 14 public function __construct ( LabelInterface $label ) { 15 $this -> label = $label ; 16 } 17 } 18 19 class LabelStarDecorator extends LabelDecorator { 20 public function render () { 21 return '** ' . $this -> label -> render () . ' **' ; 22 } 23 } 24 25 class LabelNewLineDecorator extends LabelDecorator { 26 public function render () { 27 return $this -> label -> render () . &quot; &quot; ; 28 } 29 } 30 31 class LabelHyphenDecorator extends LabelDecorator { 32 public function render () { 33 return str_replace ( ' ' , '-' , $this -> label -> render ()); 34 } 35 }
    • Decorator Example 1 < ?php 2 3 require_once ( 'Label.php' ); 4 5 $basic_label = new BasicLabel (); 6 $basic_label -> label = &quot;Hello World&quot; ; 7 echo $basic_label -> render (); 8 9 $label = new LabelNewLineDecorator ( new LabelStarDecorator ( $basic_label )); 10 $label = new LabelNewLineDecorator ( new LabelStarDecorator ( new LabelHyphenDecorator ( $basic_label ))); 11 $label = new LabelNewLineDecorator ( new LabelHyphenDecorator ( new LabelStarDecorator ( $basic_label )));
    • Observer
      • Watches for changes in another object
      • Responds to those changes
      • Target class is aware, notifies observing classes
      • Example: a map showing where event attendees are located - needs to update when list updates
    • Observer Example 3 class AttendeeList { 4 private $attendees ; 5 private $observers ; 6 7 public function addAttendee ( $id , $name ) { 8 $this -> attendees [ $id ] = $name ; 9 $this -> notify (); 10 } 11 12 public function removeAttendee ( $id ) { 13 unset ( $this -> attendees [ $id ]); 14 $this -> notify (); 15 } 16 17 public function notify () { 18 foreach ( $this -> observers as $ob ) { 19 $ob -> update ( $this ); 20 } 21 } 22 23 public function registerObserver ( $observer ) { 24 $this -> observers [] = $observer ; 25 } 26 }
    • Observer Example AttendeeList Map Invites ...
    • Resources
      • Books
        • Design Patterns: Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph Johnson and John Vlissides (&quot;Gang of Four&quot;)
        • php|architect’s Guide to PHP Design Patterns by Jason Sweat
        • Patterns of Enterprise Application Architecture by Martin Fowler (&quot;PoEAA&quot;)
      • Jason Sweat speaking on Design Patterns (Friday morning at TEK-X)
      • http://www.fluffycat.com/PHP-Design-Patterns/
    • Documentation
    • API Docs
      • Documentation generated from source code itself
      • Follows code structure
        • classes
        • inheritance
        • methods
        • parameters
    • PHPDocumentor
    • PHPDocumentor
      • PHPDocumentor
        • http://www.phpdoc.org/
      • Uses reflection
      • Comments for additional information
      • Add descriptions to the documentation
    • PHPDocumentor Comments 1 < ?php 2 3 class AttendeeList { 4 private $attendees ; 5 private $observers ; 6 7 /** 8 * Add an attendee to the list 9 * 10 * @param integer $id Attendee identifier/array index 11 * @param string $name Full name of the attendee 12 * @access public 13 * @return boolean If attendee was successfully added 14 */ 15 public function addAttendee ( $id , $name ) { 16 $this -> attendees [ $id ] = $name ; 17 $this -> notify (); 18 } 19 20 }
    • Generating PHPDoc Output
      • Two main interfaces
        • Command line, e.g.
          • phpdoc -o HTML:frames:earthli -f sample1.php -t docs
        • Web Interface
      • IDE Plugins
    • End-User Documentation
    • Come again?
      • Narrative documentation for developers
      • Often describes architecture, theory, and design patterns used
      • Typically includes many example use cases
    • What should you use?
      • Wikis
        • Easy for others to contribute
        • Typically un-distributable, never mind offer in alternate formats
        • Difficult to translate
        • Usually un-versioned
    • What should you use?
      • HTML
        • Easy for people with any web background to contribute
        • Distributable, but difficult to offer in alternate formats
        • Can be translated
        • Can be versioned
    • What should you use?
      • Docbook XML
        • Reasonably easy for people with a web background to contribute; easier if you establish standards
        • Distributable, and trivial to offer in alternate formats (e.g., HTML, Windows Help files (CHM), PDF, man pages, etc.)
        • Can be translated
        • Can be versioned
    • Docbook Example <?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <sect1 id = &quot;some.component&quot; > <title> Using Some Component </title> <para> This is a thorougly magical, catch-all component. <ulink url = &quot;http://wikipedia.com/&quot; > Wikipedia </ulink> may have more info. </para>
    • Docbook Example <example id = &quot;some.component.example&quot; > <title> Example </title> <programlisting lang = &quot;php&quot; > <![CDATA[ $foo = new Component(); ]] ></programlisting> </example>
    • Docbook Example <sect2 id = &quot;some.component.more-info&quot; > <title> More information </title> <itemizedlist> <listitem><para> Not much! </para></listitem> </itemizedlist> </sect2> </sect1>
    • Tools You Will Need
      • xsltproc
        • http://xmlsoft.org/XSLT/xsltproc2.html
      • PhD (PHP Documentor)
        • http://doc.php.net/phd/docs/
    • Beyond API Docs
      • Tutorials
      • Installation instructions
      • Examples
      • FAQs
      • Forums
      • User-contributed
    • Be a User-Contributor
      • Answer forum questions
      • Hang out on the IRC channel
      • Help with official project documentation
      • Blog
        • http://www.lornajane.net
        • http://weierophinney.net/matthew/
    • Testing
    • Why Test?
      • Makes future maintenance of the code easier
        • Defined expectations
        • Known behaviors
        • Identify early when changes in code break existing behaviors
    • Why Test?
      • Quantify the quality of your code
        • Code coverage (not the best metric)
        • Self-documented behaviors via unit tests
    • Why Test?
      • Warm fuzzy feeling from seeing green
    • What testing is not:
      • Reloading
    • What testing is not:
      • var_dump()
    • Testing is …
      • Reproducible
    • Testing is …
      • Automatable
    • Good testing includes …
      • Defined behaviors
      • Code examples of use cases
      • Expectations
    • Testing frameworks
      • PHPT
        • Used by PHP project, some PEAR libraries
      • SimpleTest
        • JUnit style testing framework
      • PHPUnit
        • JUnit style testing framework; de facto standard
    • How to test
      • Create a test case class
        • Usually named after the unit or class you're testing
      class Css2XpathTest extends PHPUnit_Framework_TestCase
    • How to test
      • What is the behavior you're testing?
        • State it in your native language &quot;Should Allow Whitespace In Descendent Selector Expressions&quot;
        • Create a method named after the behavior public function testShouldAllowWhitespaceInDescendentSelectorExpressions()
        • Capture the code that should create the behavior $test = Css2Xpath::transform('child > leaf');
        • Create assertions indicating the expected results $this->assertEquals(&quot;//child/leaf&quot;, $test);
    • How to test
      • Run the tests
        • Success? Move on to the next behavior
        • Failure?
          • Check your test assumptions and assertions
          • Check your code and correct it
          • Re-run the tests to verify
    • Other Testing Topics
      • Test Doubles
        • Stubs Replacing an object with another so that the system under test can continue down a path.
        • Mock Objects Replacing an object with another and defining expectations for it.
    • Other Testing Topics
      • Test Coverage What lines were executed, and how many times?
      • Conditional tests Testing only when certain environmental conditions are met.
      • Functional and Integration tests Testing that the systems a unit interacts with all respond as expected.
    • Adding tests to existing, untested projects
      • Create tests:
        • Whenever you introduce new features, for those features
        • Whenever you attempt to fix a bug
          • Capture the desired behavior in a unit test
          • Fix the bug
        • Whenever you refactor
    • Test-Driven Development
      • Capture behaviors individually and iteratively in unit tests
      • Write code to make the tests pass
      • Allows for playing with APIs before you've committed to coding them
      • Often hard to get into the rhythm; once you do, often hard to quit
    • Takeaways
      • Testing is easy
      class Css2XpathTest extends PHPUnit_Framework_TestCase { public function testShouldAllowWSInDescendentSctrExpressions() { $test = Css2Xpath::transform( 'child > leaf' ); $this ->assertEquals( &quot;//child/leaf&quot; , $test ); } }
    • Takeaways
      • Test whenever you can -- preferably ALWAYS
      • Automate your test suite (next topic!)
    • Quality and CI
    • Static Analysis
      • Analysing code without execution
      • Evaluating code properties and patterns
      • Common tools
        • Lines of code ( http://github.com/sebastianbergmann/phploc )
        • Code sniffer ( http://pear.php.net/PHP_CodeSniffer )
        • Mess detector ( http://phpmd.org/ )
    • Lines of Code
      • Born from PHPUnit
      • Available via PHPUnit's PEAR channel
      • Shows lots of stats about a codebase
      • Methods, lines per method
      • Cyclomatic complexity: a measure of branching points in code
      • E.g. when applied to wordpress:
    • Lines of Code Example * phploc 1.3.2 by Sebastian Bergmann. Directories: 29 Files: 295 Lines of Code (LOC): 138661 Cyclomatic Complexity / Lines of Code: 0.19 Comment Lines of Code (CLOC): 43498 Non-Comment Lines of Code (NCLOC): 95163 * example from http://techportal.ibuildings.com/2010/01/28/phploc-php-lines-of-code/
    • Lines of Code Example Interfaces: 0 Classes: 168 Abstract: 0 (0.00%) Concrete: 168 (100.00%) Lines of Code / Number of Classes: 377 Methods: 1973 Scope: Non-Static: 1972 (99.95%) Static: 1 (0.05%) Visibility: Public: 1964 (99.54%) Non-Public: 9 (0.46%) Lines of Code / Number of Methods: 32 Cyclomatic Complexity / Number of Methods: 5.44 Functions: 1599 Constants: 272 Global constants: 272 Class constants: 0
    • Code Sniffer
      • Associated with coding standards
      • Configurable &quot;sniffs&quot; to look for different properties
    • Code Sniffer Example * 1 < ?php 2 3 class recipe 4 { 5 6 protected $_id ; 7 8 public $name ; 9 10 public $prep_time ; 11 12 function getIngredients () { 13 $ingredients = Ingredients :: fetchAllById ( $this -> _id ); 14 return $ingredients ; 15 } 16 } * example from http://techportal.ibuildings.com/2009/10/12/usphp_code_sniffer/
    • Code Sniffer Example FILE: /home/lorna/phpcs/recipe.php ------------------------------------------------------------------- FOUND 8 ERROR(S) AND 0 WARNING(S) AFFECTING 5 LINE(S) ------------------------------------------------------------------- 2 | ERROR | Missing file doc comment 3 | ERROR | Class name must begin with a capital letter 3 | ERROR | Missing class doc comment 6 | ERROR | Protected member variable &quot;_id&quot; must not be prefixed | | with an underscore 12 | ERROR | Missing function doc comment 12 | ERROR | Opening brace should be on a new line 13 | ERROR | Line indented incorrectly; expected at least 8 | | spaces, found 1 13 | ERROR | Spaces must be used to indent lines; tabs are not | | allowed ------------------------------------------------------------------- output of running recipe.php through PEAR sniffs
    • Mess Detector
      • Uses some &quot;rule of thumb&quot; metrics
      • Tells you about the codebase, at a macro level
      • Can catch
        • long class/method names and parametere lists
        • complex code
        • classes with too many public methods
        • other &quot;bad smells&quot;
      • Under development
    • Continuous Integration (CI)
    • Continu … what?
      • Originally, automated build systems for compiled languages
      • Used in PHP to run unit tests, build documentation, etc.
      • Basically, any documentation or QA tool we've talked about can and should be automated
    • Basics
      • System typically monitors commits
        • Have a post-receive/commit hook trigger a build
        • Have cron/sleep processes that periodically wake up and check for new commits
      • A PHP Build …
        • Runs tests,
        • Runs QA tools (mess detection, etc.),
        • Builds documentation
    • Solutions
      • Ant: http://ant.apache.org/
        • Not CI by itself, but a build system
      <?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <project name = &quot;zend_framework_current&quot; default = &quot;build&quot; basedir = &quot;.&quot; > <property name = &quot;output.dir&quot; value = &quot;${basedir}/build&quot; /> <target name = &quot;build&quot; depends = &quot;clean, checkout, apidoc, test&quot; /> <target name = &quot;checkout&quot; > <exec executable = &quot;svn&quot; dir = &quot;${basedir}&quot; > <arg line = &quot;co http://framework.zend.com/svn/framework/branch/release-1.10 source&quot; /> </exec> </target> <!-- ... --> </project>
    • Solutions
      • Phing: http://phing.info/trac/
        • PHP Ant clone; again, not CI, but a build tool
      <?xml version = &quot;1.0&quot; encoding = &quot;UTF-8&quot; ?> <project name = &quot;tekx&quot; basedir = &quot;.&quot; > <property file = &quot;build.properties&quot; /> <target name = &quot;default&quot; > <echo message = &quot;Hello, attendees!&quot; /> </target> </project>
    • Solutions
      • CruiseControl: http://cruisecontrol.sourceforge.net/
        • Uses Ant under the hood
      <cruisecontrol> <project name = &quot;zend_framework_current&quot; <schedule interval = &quot;86400&quot; > <ant anthome = &quot;apache-ant-1.7.0&quot; buildfile = &quot;projects/${proje </schedule> <modificationset quietperiod = &quot;0&quot; > <svn LocalWorkingCopy = &quot;projects </modificationset>
    • Solutions
      • CruiseControl
    • Solutions
      • phpUnderControl: http://www.phpundercontrol.org/
        • Superset of CruiseControl with built-in support for PHPUnit, CodeSniffer, and more.
    • Solutions
      • Hudson: http://hudson-ci.org/
        • Oracle OSS project, written in Java, under active development.
        • Also uses Ant for build configuration
        • PHPUnit support via a generic xUnit plugin
        • Support for other PHP tasks via a Phing plugin
    • Solutions
      • Bamboo: http://www.atlassian.com/software/bamboo/
        • Commercial Java CI solution
        • Can use Ant or Maven
        • Most PHP QA tools export logs to formats compatible with equivalent Java tools; Bamboo simply uses these logs.
    • Takeaways
      • Automate your QA tasks
        • Find issues early
        • Fix them before deployment
      • Use continuous integration solutions to perform the automation
    • Resources
      • Sebastian Bergmann's talk &quot;The State of QA Tools in PHP&quot;
      • http://phpqatools.org
      • http://phpqabook.com
    • Deployment
    • Why You Need A Process
      • Many steps for live deploy
      • Wrap into one step, you won't miss anything
      • It'll be done the same way by everyone
      • You can roll back
        • (if you build that into your process)
    • Deployment Tools
      • Hand-spun scripts
      • Phing
        • http://phing.info/trac/
      • Capistrano (Ruby)
        • http://www.capify.org/index.php/Capistrano
    • Further Reading
      • http://phpdeveloper.org
      • http://devzone.zend.com
      • http://techportal.ibuildings.com
    • Thanks
      • http://joind.in/1563