SlideShare a Scribd company logo
Object-Oriented ProgrammingHow to melt your brain with PHPDay 2, “The Revenge”
Quick Refresher/Warm-upDesign a User classWhat properties should it have?What methods?Including getters/settersWhat are some likely child classes?
Abstract Classes/MethodsFlags a class/method as “incomplete”Classes w/abstract method(s) must be abstractInstantiating an abstract class throws a PHP errorExamples
InterfacesA list of methods a class must haveUses “implements” keywordPreferred way to do type hintingCan define properties/constants tooExampleHoneyJar implements BearFood
Overriding methodsChild classes can redefine parent methodsDepends on visibilityCan call original version with parent::methodName()
Overloading methodsDefining multiple methods with the same name, but accepting different arguments Not natively supported in PHPTo fake it, use func_get_args()
Question breakAnything we covered so farReview from yesterday is fine too
Final keywordPrevents a method from being changed in child classesCan also apply to a class as a wholeThis is the only way to make properties finalNot very commonExample
Magic methodsStart with __, like __construct()Called automatically when certain things happenExamples:__toString()__get() and __set()__clone()__sleep() and __wakeup()
ExceptionsErrors as objectsNative PHP errors or user-definedthrow new Exception();Allows use of try/catch blocksSPL adds new Exception typesErrorException object
Static keywordAdds functionality directly to a class itselfDoesn’t require instantiation to useNo access to $thisCan make things harder to testExampleArrayUtilsSession::start()
Class autoloadingDefine function(s) to tell PHP where to find undefined classesCan define multiple functions with spl_autoload_register()Zend or PEAR naming conventionsBear_Polar lives at Bearolar.php on the file system
Testing object equality$a = $bCreate a reference$a == $bType compare only$a === $bDo $a and $b point to the exact same objectinstanceofTests “is, extends, or implements”if ($dtinstanceofDateTime) {…}
Object cloningHow to actually copy an object$a = $b just makes a reference$a = clone($b) makes an actual new object__clone() magic method
Object serializationConvert an object to a string for storageCommonly used when storing objects in a session file or a db“object” or “document” databases like MongoDB use this heavilyserialize() / unserialize()__sleep() and __wakeup()
Example PHP core objectsEasySimpleXMLDateTimeMore powerful/complexDomDocumentPDOHonorable mentionmysqli
Best Practices - DocumentationLearn and use the PHP Docblock syntaxAnnotations are becoming more popular/powerfulIDEs use this info to help youCan also generate skeleton docs for youPHPDocumentor
Dependency Inversion/InjectionDon’t look for things, ask for themIf your class need a db connection, make it a required constructor argumentMakes code easier to modify/testDependencies are explicit
Design PatternsWidely-accepted solutions to common problemsOften language-neutral (i.e. steal from Java)Anti-patterns/“code smells”“You fell for one of the classic blunders”
Example Design PatternsExamplesFactory (and Factory Method)Value ObjectActiveRecordExample anti-patternGod Class
PolymorphismBehavior determined by class/subclassUsing same method name, just different implementationsSimplifies logic, better encapsulationExampleFrom Wikipedia: polymorphism.phpDataWriter
Unit TestingWriting tests (in PHP) to verify your codeTest the smallest possible chunks (units) of codeTest for results, not implementationEvery requirement/bug should have testsPHPUnitMost IDEs can build test skeletons for you
Questions?This is your last chance…
Final exam!Design a blog using OO principlesRequirements:Users must be authenticated to submit contentComments are allowedProduce a list of the most recent 10 entries
Final exam!Write a simple Database Abstraction Layer (DBAL)Requirements:Supports Oracle and MySQLSupports bound query parametersCan fetch, add, update, and remove recordsImplements the ExampleDBAL interface
ResourcesThe gold standard for OO code:http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29PHPUnithttp://www.phpunit.de (it’s in English)PHPDocumentorhttp://www.phpdoc.org/Code Complete 2An actual book, and a massive one at thathttp://www.phpfreaks.com/tutorial/oo-php-part-2-boring-oo-principlesThis covers a lot of the SOLID stuff in more detail

More Related Content

OOP Day 2

  • 1. Object-Oriented ProgrammingHow to melt your brain with PHPDay 2, “The Revenge”
  • 2. Quick Refresher/Warm-upDesign a User classWhat properties should it have?What methods?Including getters/settersWhat are some likely child classes?
  • 3. Abstract Classes/MethodsFlags a class/method as “incomplete”Classes w/abstract method(s) must be abstractInstantiating an abstract class throws a PHP errorExamples
  • 4. InterfacesA list of methods a class must haveUses “implements” keywordPreferred way to do type hintingCan define properties/constants tooExampleHoneyJar implements BearFood
  • 5. Overriding methodsChild classes can redefine parent methodsDepends on visibilityCan call original version with parent::methodName()
  • 6. Overloading methodsDefining multiple methods with the same name, but accepting different arguments Not natively supported in PHPTo fake it, use func_get_args()
  • 7. Question breakAnything we covered so farReview from yesterday is fine too
  • 8. Final keywordPrevents a method from being changed in child classesCan also apply to a class as a wholeThis is the only way to make properties finalNot very commonExample
  • 9. Magic methodsStart with __, like __construct()Called automatically when certain things happenExamples:__toString()__get() and __set()__clone()__sleep() and __wakeup()
  • 10. ExceptionsErrors as objectsNative PHP errors or user-definedthrow new Exception();Allows use of try/catch blocksSPL adds new Exception typesErrorException object
  • 11. Static keywordAdds functionality directly to a class itselfDoesn’t require instantiation to useNo access to $thisCan make things harder to testExampleArrayUtilsSession::start()
  • 12. Class autoloadingDefine function(s) to tell PHP where to find undefined classesCan define multiple functions with spl_autoload_register()Zend or PEAR naming conventionsBear_Polar lives at Bearolar.php on the file system
  • 13. Testing object equality$a = $bCreate a reference$a == $bType compare only$a === $bDo $a and $b point to the exact same objectinstanceofTests “is, extends, or implements”if ($dtinstanceofDateTime) {…}
  • 14. Object cloningHow to actually copy an object$a = $b just makes a reference$a = clone($b) makes an actual new object__clone() magic method
  • 15. Object serializationConvert an object to a string for storageCommonly used when storing objects in a session file or a db“object” or “document” databases like MongoDB use this heavilyserialize() / unserialize()__sleep() and __wakeup()
  • 16. Example PHP core objectsEasySimpleXMLDateTimeMore powerful/complexDomDocumentPDOHonorable mentionmysqli
  • 17. Best Practices - DocumentationLearn and use the PHP Docblock syntaxAnnotations are becoming more popular/powerfulIDEs use this info to help youCan also generate skeleton docs for youPHPDocumentor
  • 18. Dependency Inversion/InjectionDon’t look for things, ask for themIf your class need a db connection, make it a required constructor argumentMakes code easier to modify/testDependencies are explicit
  • 19. Design PatternsWidely-accepted solutions to common problemsOften language-neutral (i.e. steal from Java)Anti-patterns/“code smells”“You fell for one of the classic blunders”
  • 20. Example Design PatternsExamplesFactory (and Factory Method)Value ObjectActiveRecordExample anti-patternGod Class
  • 21. PolymorphismBehavior determined by class/subclassUsing same method name, just different implementationsSimplifies logic, better encapsulationExampleFrom Wikipedia: polymorphism.phpDataWriter
  • 22. Unit TestingWriting tests (in PHP) to verify your codeTest the smallest possible chunks (units) of codeTest for results, not implementationEvery requirement/bug should have testsPHPUnitMost IDEs can build test skeletons for you
  • 23. Questions?This is your last chance…
  • 24. Final exam!Design a blog using OO principlesRequirements:Users must be authenticated to submit contentComments are allowedProduce a list of the most recent 10 entries
  • 25. Final exam!Write a simple Database Abstraction Layer (DBAL)Requirements:Supports Oracle and MySQLSupports bound query parametersCan fetch, add, update, and remove recordsImplements the ExampleDBAL interface
  • 26. ResourcesThe gold standard for OO code:http://en.wikipedia.org/wiki/Solid_%28object-oriented_design%29PHPUnithttp://www.phpunit.de (it’s in English)PHPDocumentorhttp://www.phpdoc.org/Code Complete 2An actual book, and a massive one at thathttp://www.phpfreaks.com/tutorial/oo-php-part-2-boring-oo-principlesThis covers a lot of the SOLID stuff in more detail

Editor's Notes

  1. User or BaseUser. Should probably have firstName, mi, lastName, phone1, phone2, areaCode, email, potentially an “authenticated” flaggetPhone, getName, plus individual chunks. Possibly authentication method but that’s a good choice to factor out to its own classLikely child classes – AdminUser, GuestUser, PowerUser, etc…Was this helpful? Should we design a small app like a blog?
  2. Most often used for “base” classesAnother way to create an “abstract” class is to have your constructor throw an ExceptionIf all of the methods in your class are abstract, then you’re better off making an Interface instead so you don’t use up your one shot at inheritance. Show BaseBear
  3. An interface is like setting a contract with users of the class. It’s a list of things that you all agree has to be there. It makes no mention of how these methods are implemented, as long as they exist. They can even be empty.This makes testing your code much easier. I’ll cover unit testing near the end of today.Still some variation on naming… some say iBearFood, some say BearFood_Interface, some say just call it BearFood (implements keyword gives it away) A quick jump back to Day 1 where we tried to type hint PoohBear…
  4. We’ve actually already used this but it certainly merits its own slide. This is a very important part of OO design.Remember that you can only override public and protected methods that aren’t final. Ideally they should keep the same method signature (params, types & defaults) too or you’ll generate E_STRICT errorsIn general it’s a good idea to call the parent constructor, if one exists, just to make sure everything got built properly. Show PolarBearFinal example of constructor
  5. I bring this up mostly for the benefit of those who have already studied other languages, especially strongly-typed languages like C++ or JavaPHP’s way to handle this would be to pass an array of arguments instead. To provide defaults, make (for example) a $_defaultOptions property and array_merge() that and the user’s passed array of $options
  6. Fairly self-explanatory. The most common use case I see for this is a protected method that the class author wants to lock down, so they will use protected final in their method signature.Private final makes no sense.
  7. The most important thing to say here is to use these sparingly, if at all. With the exception of __construct() these are more like shortcuts or crutches. Relying on magic makes your code harder to understand. They’re also significantly slower than using native code. The PHP manual has a list of all of the available magic methods. Don’t start method names with __ in case of future conflicts. The only ones I’d really use would be __construct, __toString, and very rarely, __destructA side note on overloading… some people refer to the use of __get and __set as “overloading” a class. Again, this term is used differently elsewhere
  8. Exceptions are like errors on steroids. You have much more control using exceptions than you do with native PHP errorsObjects, so you can type hint. Try/catch is really powerful error handling. Remember to release expensive resources in catch block if your program is giving up to mitigate DoS attacksExceptions are by far the most common use of “empty” classes. If you want to extend a native PHP Exception and just change the name, that’s both allowed and encouragedExceptions have useful methods like getMessage, getFile, getLine, etc…
  9. Sometimes you have functionality that you want to contain in a class, but you need or want to use it without having to instantiate an object first. Since you aren’t working with an instantiated object, you can’t use the $this keyword in static methods, even If you’re calling a static method from an object instanceThe best use of static methods I can think of is either a “Utilities” class to group related custom functions, like StringUtilities or ArrayUtilities, OR a class that doesn’t persist any data, like the Session class from the web forum
  10. I promised to show you how to avoid typing require_once 30 times/app, and here it is. In PHP4 you could define a function called __autoload() that would run if a class wasn’t found. Now in PHP5 you can define as many autoloaders as you want using the SPLNaming conventions become very important here. If you follow them strictly your autoload functions become much easier to write. We recommend following the Zend or PEAR standard here. They’re nearly identical. Case matters.A further advantage of autoloading is it lets you “lazy load” only the code you actually need for a request. This can result in less code being run than requiring the entire pile of functions every time.
  11. I originally called this slide “comparing objects” but then I’d also have to get into how to test if an object is greater than another object, less than, etc… and that was just too much. The slide basically speaks for itself, but the main takeaway here should be to always use strict comparison (===) or instanceofinstanceof can also test interfaces and parent classes. PolarBearinstanceof Bear would evaluate to true since PolarBear extends Bear. Type hinting is based on instanceof
  12. Object cloning is rarely used in my experience. This tends to be more of a gotcha than a feature. The only time I’ve used clone that I can remember was on a calendar. I made a start DateTime object, cloned it, and added a week to the clone so I could have an end DateTime object.
  13. I used to advocate storing lots of objects as strings from page to page for the sake of speed, but building objects is cheap, and if you’re not careful you can lose some property values during serialize/unserialize, esp. references to a db connectionThat being said, I do recommend making a few objects, serializing them, and echoing them out to the screen just so you can get a bit of practice decoding the format. I’ve found that knowledge to be very helpful several times. For example, PEAR stores its configuration information as a serialized object, so knowing how to read the format means you can edit that file directly. It’s basically type/length/value
  14. This is just a sample of some of the built-in PHP objects. SimpleXML really is a dead-simple way of interacting with XML in an object-oriented format. Every node is a document tree becomes a SimpleXML instance. DateTime we already covered.I never use DomDocument or PDO directly, so if you want more information on them, check the docs. That being said, nearly every DBAL written for PHP is based off of PDO, so you should at least learn how to build a PDO connection stringI just bring up mysqli here because it was one of the first PHP objects I used heavily. Converting an app from mysql functions to mysqli methods was good early syntax practice
  15. Everybody hates documentation, but in this case a smart IDE can make documentation easier to write and useful to YOU while you’re coding. Again, we recommend following the documentation standard that goes with the Zend or PEAR coding standardsThings like @param or @return are called annotations, and they are used by IDEs to help you with code completion and to fill in informational pop-ups. Also, several coding projects (including PHPUnit, which we’ll get to later) add even more power to annotations, to the point where they can affect the functionality of codeLast trick: PHPDocumentor is a FOSS project to scrape your code for docblocks and generate a really robust set of API documentation for your code in a variety of formats, even PDF
  16. Remember from Day 1 when we turned most of the Bear’s properties into constructor arguments? This is why. If you need to test your class, you can pass in fake versions of what it needs without modifying the class itself, ex. A db connection that doesn’t issue any queriesMakes it easier to see how classes relate to each other and in what order they need to be builtRule of thumb: you should not have the “new” keyword inside a class unless that class’s sole purpose is to build objects (called a Factory) OR you’re building a simple Value Object (sometimes OK)
  17. I love design patterns. They’re like having a math textbook that has the answers to all the odd-numbered problems in the back. In the past 40 years or so programmers have run into many of the same problems over and over again, and design patterns are like those solutions that have risen to the top of the pile, like a coder’s version of a solutions knowledgebase. Most of them are designed around OO principles rather than being language-specific, and many are segmented enough that you can find objects already written whose sole purpose is to implement a specific pattern in your code.
  18. A Factory is an object whose purpose is to build other objects. Advantages: centralized logic for “constructors”. Allows running additional setup methods. Can allow object caching. A Factory Method is the same thing only as a single method instead of a whole class (ex. PEAR Mail)A Value Object is a very small, lightweight object designed to add just a little bit more functionality to a “primitive type” like an integer or string. Classic example is a Money object: can do currency conversion and know what type of digit separator to use. DateTime is another example of a Value Object, as is GenderActiveRecord is a somewhat Microsoft-centric way of dealing with databases. An “ActiveRecord” object will have methods to query the database for a collection of rows, and then it will populate the object’s properties with the values of the “current” recordA God Class is a class that is all knowing and all seeing… in other words it’s way too large and breaks the “single responsibility” principle. A good warning for this is if the best name you can come up with for your object is the name of the app itself. If you can’t figure out what to name a class there’s a good chance you need to rethink its design. The same holds true with methods too, and even variables if you’re picky enough.
  19. From being involved in several programmer interviews, I can say that most people get this wrong. It’s somewhat tricky to explain because it involves several different concepts that mean different things in different contexts, so if this doesn’t make sense until after the example that’s perfectly fine. Polymorphism, to me, means having multiple objects with the same method signature, and the code that uses them doesn’t know or care which is which. The type of the object (rather than the method used) determines the outcome. It is ideally suited to the Factory pattern
  20. The best example I can give for this is one of a car. If you were going to “unit test” a car, you would individually test as many pieces as you could, like testing the knob on the radio, the turn signal, the spark plug, etc… then the only real test you’d have left is turning it on and driving it to make sure all the pieces were hooked together properly. Testing everything as a whole is called a functional test.Having a full test suite lets you make changes in your code and knowing immediately if your changes break anything. It’s a really liberating feeling, and writing tests for your code will make you think about both the design of the code and a lot of the edge cases that you might not have coded for originally.The true pinnacle of this philosophy is called Test-Driven Development, in which you write the tests for your code before you write your code. Writing tests for TDD becomes part of your app design process because the tests determine your API.
  21. I’m kidding of course, but if you DO have questions about anything we’ve covered in either day, now would be a good time to ask them.
  22. Feel free to work in pairs or small groups on this. You can easily use 6 or more objects for this so don’t be stingy. For extra credit you can start coding the objects, or at least produce interfaces for them.
  23. Feel free to work in pairs on this. I do expect it to take awhile and we’ll be around to help if you have questions. I recommend starting with MySQL first.
  24. Parting thoughts: problems are MUCH cheaper to fix earlier on in the process. It’s almost always worth it to put some serious thought into the design/requirements part of an app BEFORE you code. Sketch it out on a piece of paper or use a mind-mapping software or flowchart. It will take a while for the OO frame of mind to sink in and become automatic, whether it’s a few months or a year or more. Don’t give up on it. Once you get it, you’ll never want to go back.