Implementing The Open/Closed Principle
Sam Hennessy




    • Originally from the UK
    • Now live in Denver, CO
    • Software Architect at i3logix
    • Ex-Pro Services Consultant For Zend
    • Regular at Front Range PHP Users Group


2
i3logix




3
What is it?




     Part of SOLID

     Protect your system from change

     Do you already do it?


4
SOLID


            S       Single responsibility
                          principle

            O      Open/closed principle


            L   Liskov substitution principle


            I      Interface segregation
                          principle


5
            D      Dependency inversion
                        principle
Open/Closed Principle




    "Be open for extension,
           but closed for
    modification."

6
And I Care Why?


                             Maintenance



               Let your
                                             Customer
            users bridge a
                                           customization
             feature gap




             Competitive                     Preventing
                edge                        the "FORK"!



                              A-la-cart
                               feature
                              offerings
7
What about YAGNI and KISS?




8
Where Can It Be Applied?


                               Class


                               Application


                               Enterprise




9
Classes
Classes




                         Inheritance




               Polymorphism            Interfaces




11
Small Methods




12
No Public Properties




                            Always be private?


                              Encapsulation


                            Information hiding


                             It's cheap to do


13
Globals and OCP




14
De-coupling




15
class Calculator{
    public function __invoke($calc, $left, $right) {
        if ($calc == 'add') {
            return $left + $right;
        } else if ($calc == 'sub') {
            return $left - $right;
        }
    }
}
class Calculator{
    public function __invoke(Calc $calc, $left, $right){
        return $calc($left, $right);
    }
}


$calculator = new Calculator();
echo $calculator(new AddCalc(), 2, 1), "n";
echo $calculator(new SubCalc(), 2, 1), "n";
interface Calc {
    public function __invoke($left, $right);
}


class AddCalc implements Calc {
    public function __invoke($left, $right) {
        return $left + $right;
    }
}


class SubCalc implements Calc {
    public function __invoke($left, $right) {
        return $left - $right;
    }
}
if ($logType == 'echo') {
    echo $message;
} else if ($logType == 'file') {
    $logger->writeToFile($message);
}
Composition Over Inheritance




20
Behavior vs. Dependencies




21
Application
Plugins




23
Service Locator




24
Dependency Injection




25
Event Driven Programming




26
Aspect Oriented Programming




27
Rules Engine




28
Build Process




29
Enterprise
Public API




31
Service Oriented Architecture (SOA)




32
Global Broadcast




33
When to break OCP!?
When to break OCP!?



                             Separation of
                               concerns




                Excessive                        Single
               duplication                   responsibility



35
Everyday vs. the Revolutionary




       Facts don't                      Feature
          fit the                      doesn't fit
         theory                       the design



36
What’s Your Strategy?
Questions?
Thanks You!

Implementing The Open/Closed Principle

Editor's Notes

  • #2 A note
  • #5 I hope to enable you to add some consistency by formalizing your thinking around OCP
  • #8 Risk of making changeLessened by good automated testing coveragePlatforms Amazon vs. GoogleTwitter
  • #9 You can apply the principle reactively
  • #10 Let’s take a look at techniques for each layer
  • #12 Traditional ideas of OCP what you be able to write the class code once and never have to come back to edit itThese techniques focus on this level changeSome of my application level techniques kind of blur the linePrevent changes to a classDoesn’t prevent change to the app, unless you are using DI or something like it
  • #13 Small is fast when it comes to changing direction10 executable lines is a good target, 20 the max (obviously there are always exceptions)
  • #14 Just one client can mess it up for everyone
  • #15 Traditional ideas of OCP say that globals break OCPThese are points of view that are just thinking about riskYou are introducing risk that other parts of the system will break this code
  • #16 Making your code ignorantAbstracting – to
  • #20 Imagine this all over your application.Then we want to add FireBug/FirePHP logging support for our Ajax calls
  • #21 Also called Composite Reuse Principle
  • #22 What’s your goal
  • #23 Can anyone think of any more class level techniques
  • #24 Lots of examples from ZFThink how this has helped word press
  • #27 Signal & SlotsPub/Sub
  • #28 Cross cutting concernsFlow 3
  • #31 Can anyone think of any more APPLICATION level techniques
  • #33 Message bus
  • #34 PubsubQueueTrue broadcast
  • #37 Martin FowlerIsolate the assumptions scattered around the code to a single element (by assumptions, you assumed they wouldn't need to change) E.g. You are echoing all over the code, but you need to support encoding to jsonThis will reduce the risk for the big change Or start from scratch
  • #38 Why are you doing this?