OOP for
Object Haters

socketwench.github.io/OOPforObjectHaters

Grrr! Objects!

What was wrong with functions?

Nothing!

(Well, almost nothing.)

What Functions Do Well

Easy to write and use.

"Assembly line" code.

When Functions Aren't Enough

No simple way to extend

No easy way to encapsulate state

PHP Doesn't Enforce Discipline

No struct leads to Arrays Of Doom.

Weak typing makes testing, documentation hard.

"I'm lost in a maze of classes all alike."

Larger structures harder to see.

Functions (and hooks) are a golden hammer.

"I shouldn't need a 400MB IDE to code!"

You don't, but it helps.

Bad IDEs can reflect poorly on the language.

"I hate this fsck'ing language!"

Bad initial experience can taint a language.

Bad Languages to Learn From

C++ has weirder, less modern OOP.

Java is a little too object happy...

PHP4 wasn't even finished. Ugh!

Abstractions vs. Concretions

"The School of Athens"

 

 

 

 

 

 

Raphael, 1511

 
 
 
 
 
 
 
 
 

Ideal Form

Abstract, only exists in your mind

Represents a class of real things

Real Objects

Physical and "concrete"

May differ from the ideal...

...but identifiable as part of the same class

Programming Plato

Defining the Platonic Chair

class Chair;
 
 
 
 
 
 

Inheritance

Extends the parent, or "base" class

Child class "inherits" aspects from the parent

Extending the Chair Class

class ComfyChair extends Chair;

class OfficeChair extends Chair;

class WeirdChair extends Chair;

IS_A Relationship

Child class is a decedent of parent class

Robot Blueprints

 
 
 
 

Defining Classes


    class Robot {
        // More stuff here.
    }
                        

Properties

"Class Variables"

Encapsulates state in the class

Defining Class Variables


    class Robot {
        protected $myVariable = 'Initial Value.';
    }
                        
 
 
 
 

Access Specifier

Precedes a property definition

public, private, or protected

 
 
 
 

"public" Specifier

Child classes inherit the property

Everyone can read & write the property

 
 
 

"private" Specifier

Child classes do not inherit the property

No one but the defining class can see or use it

 
 
 

"protected" Specifier

Property stays "within the family".

Unrelated classes do not see or have it.

Drawing Properties

Classes Can Be Properties Too!

Define them like you would any other variable


    class Battery {}

    class Robot {
        protected $battery;
    }
                        

HAS_A Relationship

Hosting class possesses hosted class

Making your Robot Go

Methods

"Class Functions"

Gives the class knobs and buttons

Defining Methods


    class Robot {
        public function myMethod($param) {
            // Method body
        }
    }
                        

Access Specifies for Methods

Controls who can call, not see.

Who ya gonna (allow) to call?

public = Everyone

private = Methods in the same class

protected = Only classes in the same family

Special Methods

Plays a special role in the language

http://php.net/manual/en/language.oop5.magic.php

Constructors

"Returns" an object of the class' type

May have parameters like other methods


    class Robot {
        public function __construct($someOption = NULL) {
            // Build the object.
        }
    }
                        

Drawing Methods

Building Robots

 
 
 

Classes are Blueprints for Objects

They're used to build your house, not be your house

Objects Live in Memory

Classes are defined in your code

One class = zero or more objects

Creating Objects

"Instantiating a class"


    $myRobot = new Robot();

    $otherRobot = new RobotBatteriesNotIncluded($battery);
                        

"new" Keyword

Calls the class's constructor method

"returns" a new object

Using Objects

-> or "arrow" operator


    $myRobot->myVariable = 'Some other value.';
    $myRobot->myMethod($param);
                        

Using Properties in Methods


    class Robot {
        public function setMyVariable($param) {
            $this->$myVariableName = $param;
        }

        public function getMyVariable() {
            return $this->myVariableName;
        }
    }
                        
(The above is called a "setter" and "getter".)

Talking to Yourself

$this keyword

Refers to object that owns the method

Robot Hierarchies

 
 
 

Doing Things Differently


    $normalGhost->slime($ghostBuster);

    $slimer->slimeLots($ghostBuster);
                        

But in use


    switch(get_class($unknown_ghost)) {
        case "Ghost":
            $unknown_ghost->slime($ghostBuster);
            break;

        case "Slimer":
            $unknown_ghost->slimeLots($ghostBuster);
            break;
    }
                        
 
 

Method Overloading


    class Ghost {
        public function slime($ghostBuster) {
            // Normal slime.
        }
    }

    class Slimer extends Ghost {
        public function slime($ghostBuster) {
            // Lots more slime!
        }
    }
                        
 

"parent" Keyword

Refers to the current class' parent class.

Not a variable! Must be accessed statically.

"::" Operator

Like ->, but static

Accesses the class, not the object

Extending, Not Reimplementing


    class Slimer extends Ghost {
        public function __construct() {
            $color = 'green';
            parent::__construct($color);
        }
    }
                        

Works on any method!

Abstract Methods

All classes in this family should do this...

...but each does it completely differently.

Defining an Abstract Method


    class Ghost {
        abstract public function frighten($person);
    }
                        
 

Abstract Classes

Abstract method = abstract class.


    abstract class Ghost {
        abstract public function frighten($person);
    }
                        

Polymorphism

Fancy word for "same name, different action".

Doodling and Diagrams

Unified Modeling Language (UML)

General software engineering modeling language

Not OOP specific, but really useful

UML is HUGE

So...don't diagram everything

Only the parts where a picture would help

Class Diagrams

Visualizes what a class is made of

How classes relate structurally to each other

 
 
 
 
 

Sequence Diagrams

Visualize when objects are created/destroyed

When and what classes "say" to each other

 
 
 
 
 
 
 
 
 

Moar UML!

http://www.uml.org/

Contractual Robots

Let's Make a Contract

You to do something

I agree to only ask you to do things you can do

Interfaces

Like a class, but lighter

Can't be created by itself, but implemented by classes

Defining Interface


    interface AstroMech {

        public function beepBoop();

        protected function navigateXwing($coordinates, $speed);

    }
                        

Interfaces have no properties

They only define what they can do...

...not how they do it or what they did.

Interface Methods

No method body

Define params as normal

Using Interfaces

implements keyword


    class R2DTwo extends BaseDroid implements AstroMech {
        ...
    }
                        

Why!?

You can only inherit once...

...but implement multiple interfaces!


    class ThreeCPO implements ProtocolDroid, LoadLiftProgrammer {
        ...
    }
                        

IS_A, HAS_A, DOES_A

What an object can do is more important

Define a completely different class "lineage"

Excellent place for documentation

Interfaces ♥ Type Hinting

Now you only depend on the interface, not class


    function myFunction(AstroMech $droid) {
        // Do something.
    }
                        

Extending Interfaces

extends keyword, just like classes


    interface R2Droid extends AstroMech {
        public function hide($lightsaber);
    }
                        

Drawing Interfaces

Playing Nice With Other Robots

 
 
 
 
 
 
 
 
 

Namespaces

Puts classes into a named box

Names need be only unique in each box

Using Namespaces in PHP


    $myDate = new \MacLeod\Date();
    $yourDate = new \Kurgan\Date();
                        
Syntax differs greatly across languages!

Defining Namespaces


    <?php
    namespace \Movies\Highlander;
                        

Must be the first line!

 

Importing


    use \Really\Long\Namespaced\Class\Name;

    $myName = new Name();
                        
 

Aliasing

Imports class and gives it a new name


    use \Movies\Highlander\Kurgan\Date as BadGuy;

    $myVar = new BadGuy();
                        

Structuring Your Project

Blanket Disclaimer

Each language does it differently

Some common patterns have emerged

One class per file

File name same as your class

File Extension

Use your languages normal extension

No *.inc for PHP

Directories

Match your namespaces

Nested namespace = nested directory


    $myDate = new \Movies\Highlander\MacLeod\Date();
                        

Root Namespace Directory

Conventions differ between languages and communities

Modern PHP uses <project_dir>/src

Working In OOP

Think in Conversations

Not in steps

Don't Fear the Whiteboard!

A little UML goes a long way

Please use an IDE!

Find one you don't hate immediately

Love Your Documentation

Helps find what you need faster

Let Go

You don't need to keep it all in your head

Further Reading

Design Patterns by Erich Gamma et. al

PHP The Right Way

Modern PHP

A Year with Symfony

Thank you!

socketwench.github.io/OOPforObjectHaters

Background by Artwyrd