SlideShare a Scribd company logo
1 of 53
Download to read offline
Singletons in
Why they are bad and how you can eliminate
       them from your applications
Gordon Oheim
   @go_oh
Singletons in PHP - Why they are bad and how you can eliminate them from your applications
a.k.a.
The GoF Book
Singleton
Creational Pattern
„control when and how objects are
            created“
“Ensure a class has only one
instance, and provide a global
     access point to it.”
Singleton
          Singleton

- instance : Singleton
- instance : Singleton

+
+   getInstance()
    getInstance()   :
                    :   Singleton
                        Singleton
-
-   __construct()
    __construct()   :
                    :   void
                        void
-
-   __clone()
    __clone()       :
                    :   void
                        void
-
-   __wakeup()
    __wakeup()      :
                    :   void
                        void
class Singleton
…
    public static function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self;
        }
        return self::$instance;
    }
}
abstract class Singleton
…
    public static function getInstance()
    {
        return isset(static::$instance)
            ? static::$instance
            : static::$instance = new static;
    }
    final private function __construct()
    {
        static::init();
    }
    protected function init() {}
}

class A extends Singleton {
    protected static $instance;
}
trait Singleton
…
    protected static $instance;
    final public static function getInstance()
    {
        return isset(static::$instance)
            ? static::$instance
            : static::$instance = new static;
    }
    final private function __construct() {
        static::init();
    }
    protected function init() {}
}

class A {
    use Singleton;
}
„Nobody should need a mechanism to make
  it as easy as pie to clutter the code base
              with singletons“

          - Sebastian Bergmann
Testing Singletons
„In my stilted view of the universe anything that
impedes testing is something to be avoided. There
 are those who don't agree with this view, but I'll
   pit my defect rates against theirs any time.“

        - Robert „Uncle Bob“ C. Martin
class TableDataGateway
…
    public function __construct()
    {
        $this->db = Db::getInstance();
    }
    public insert(array $data)
    {
        $this->db->sql('INSERT …', $data);
    }
}
class TableDataGatewayTest extends PHPUnit…
    /**
     * @dataProvider provideInsertData
     */
    public function testInsertCallsDbWithData($data)
    {
        $gateway = new TableDataGateway;
        $gateway->insert($data);
        $this->assertSame(
            $data,
            $gateway->findById($data['id'])
        );
    }
}
throws LogicException:
No key found for 'pdo' in Registry
class Db extends Singleton
…
    protected function init()
    {
        $this->logger = Logger::getInstance();
        $this->pdo = new PDO(Registry::get('pdo'));
    }
    public sql($query, $data)
    {
        $this->logger->log(printf(
        'Executed %s with %s',
            $query,
            implode(',', $data)
        ));
        $sth = $this->pdo->prepare($query);
        return $sth->execute($data);
    }
}
Singletons are pathological liars
          - Miško Hevery
class TableDataGatewayTest extends PHPUnit…
    /**
     * @dataProvider provideInsertData
     */
    public function testInsertCallsDbWithData($data)
    {
        Registry::set('pdo', array('…'));
        Registry::set('log', '/dev/null');
        $gateway = new TableDataGateway;
        $gateway->insert($data);
        $this->assertSame(
            $data,
            $gateway->findById($data['id'])
        );
    }
}
Your tests are not isolated.
    You still need a real database.
No easy way to mock the Db Singleton.
„The real problem with Singletons is that they
give you such a good excuse not to think carefully
  about the appropriate visibility of an object.“

                   - Kent Beck
Hard to change code
  manifests itself in a cascade of
subsequent changes in dependent
               code
Fragile code
breaks in many places when you
     change just one place
Non-reusable code
   is code that you cannot reuse in
another project because it contains too
         much extra baggage
S.O.L.I.D.
Single Responsibility Principle

A class should have one, and only one,
           reason to change.
Open Closed Principle

You should be able to extend a classes
   behavior, without modifying it.
Liskov Substitution Principle

Derived classes must be substitutable
       for their base classes.
Interface Segregation Principle

Make fine grained interfaces that are client
                specific.
Dependency Inversion Principle
Depend on abstractions, not on concretions.
Solid Singleton?
SRP Violation

 Creation Logic + Business Logic
      = 2 reasons to change

Mitigated by using Abstract Singletons

 But responsibilities are still strongly
     coupled through inheritance
OCP Violation

In PHP < 5.2 Singletons are closed for extending

 Boilerplate code has to be removed when no
                longer needed
DIP Violation

  Global access breaks encapsulation

         Hides dependencies

Adds concrete dependencies into Clients

            Signature lies
Singletons in the Wild
Config              FooController
                                 Response
    FrontController
ThatService
       Request                Cache
                   Database
 Application              BarController
        Registry         Logger
   ThisService
                 Bootstrap            Acl
Config              FooController
                                 Response
    FrontController
ThatService
       Request                Cache
                   Database
 Application              BarController
        Registry         Logger
   ThisService
                 Bootstrap            Acl
Recap:
 “Ensure a class has only one
instance, and provide a global
     access point to it.”
„So much of the Singleton pattern is about
 coaxing language protection mechanisms into
protecting this one aspect: singularity. I guess it
is important, but it seems to have grown out of
                  proportion.“

              - Ward Cunningham
You do not need to ensure singularity
when you are going to instantiate the
     object only once anyway.
You do not need to provide a Global
Access Point when you can inject the
              object.
class TableDataGateway
…
    public function __construct()
    {
        $this->db = Db::getInstance();
    }
}

class Db extends Singleton
…
    protected function init()
    {
        $this->logger = Logger::getInstance();
        $this->pdo = new PDO(Registry::get('pdo'));
    }
}
class TableDataGateway
…
    public function __construct(Db $db)
    {
        $this->db = $db;
    }
}

class Db
…
    public function __construct(PDO $pdo, Log $logger)
    {
        $this->logger = $logger;
        $this->pdo = $pdo;
    }
}
But then I have to push dependencies all
  the way through my object graph?!
Recap:
       Creational Pattern
„control when and how objects are
            created“
Use Builders and Factories to
 create Collaborator Graphs
class UserControllerBuilder
{
    public function build($config)
    {
        $log = new Log($config['log']);
        $pdo = new PDO($config['…']);
        $db = new Db($pdo, $log);
        $tdg = new TableDataGateway($db);
        return new UserController($tdg);
    }
}
class UserControllerBuilder
{
    public function build($config)
    {
        $log = new Log($config['log']);
        $pdo = new PDO($config['…']);
   ??? $db = new Db($pdo, $log);
        $tdg = new TableDataGateway($db);
        return new UserController($tdg);
    }
}
class UserControllerBuilder
{
    public function build($config)
    {
        $db = new LogDecorator(
            new PDO($config['…']);
            new Log($config['log']);
        );
        $tdg = new TableDataGateway($db);
        return new UserController($tdg);
    }
}
// index.php
include '/path/to/autoload.php';
$config = new Config('/path/to/config.ini');
$router = new Router(
    array(
      '/user/{id}' => function() use ($config)
      {
        $builder = new UserControllerBuilder;
        return $builder->build($config);
      }
    )
);
$router->route(
    new Request($_GET, $_POST, $_SERVER),
    new Response
);
„Singletons aren't necessary
when you can design or redesign
    to avoid using them.“

        - Joshua Kerievsky
„I'm in favor of dropping Singleton.
 Its use is almost always a design
               smell“

            - Erich Gamma

More Related Content

What's hot

[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화NAVER D2
 
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017Amazon Web Services Korea
 
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) :: 한국 카오스엔지니어링 밋업
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) ::  한국 카오스엔지니어링 밋업Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) ::  한국 카오스엔지니어링 밋업
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) :: 한국 카오스엔지니어링 밋업Channy Yun
 
Annotations in PHP: They Exist
Annotations in PHP: They ExistAnnotations in PHP: They Exist
Annotations in PHP: They ExistRafael Dohms
 
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...Amazon Web Services Korea
 
JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011Kris Mok
 
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017AWSKRUG - AWS한국사용자모임
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016Amazon Web Services Korea
 
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena DollyJi-Woong Choi
 
Modern Incident Management with Atlassian (오픈소스컨설팅)
Modern Incident Management with Atlassian (오픈소스컨설팅)Modern Incident Management with Atlassian (오픈소스컨설팅)
Modern Incident Management with Atlassian (오픈소스컨설팅)Open Source Consulting
 
Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Hyun-Mook Choi
 
코드로 인프라 관리하기 - 자동화 툴 소개
코드로 인프라 관리하기 - 자동화 툴 소개코드로 인프라 관리하기 - 자동화 툴 소개
코드로 인프라 관리하기 - 자동화 툴 소개태준 문
 
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)Amazon Web Services Korea
 
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar Amazon Web Services Korea
 
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon Web Services Korea
 
좌충우돌 Data Engineering 학습기
좌충우돌 Data Engineering 학습기좌충우돌 Data Engineering 학습기
좌충우돌 Data Engineering 학습기DONGMIN LEE
 
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018Amazon Web Services Korea
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용흥배 최
 
F5_Active-Active Data Center.pdf
F5_Active-Active Data Center.pdfF5_Active-Active Data Center.pdf
F5_Active-Active Data Center.pdfSolutions Architect
 

What's hot (20)

[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화[2D1]Elasticsearch 성능 최적화
[2D1]Elasticsearch 성능 최적화
 
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017
Amazon SNS로 지속적 관리가 가능한 대용량 푸쉬 시스템 구축 여정 - AWS Summit Seoul 2017
 
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) :: 한국 카오스엔지니어링 밋업
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) ::  한국 카오스엔지니어링 밋업Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) ::  한국 카오스엔지니어링 밋업
Chaos Engineering 시작하기 - 윤석찬 (AWS 테크에반젤리스트) :: 한국 카오스엔지니어링 밋업
 
Annotations in PHP: They Exist
Annotations in PHP: They ExistAnnotations in PHP: They Exist
Annotations in PHP: They Exist
 
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...
[Games on AWS 2019] AWS 사용자를 위한 만랩 달성 트랙 | AWS에서 분산 서비스 거부 공격(DDoS)을 고민하지 않는 ...
 
JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011JVM @ Taobao - QCon Hangzhou 2011
JVM @ Taobao - QCon Hangzhou 2011
 
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017
AWS 기반 5천만 모바일 앱서비스 확장하기 - 이영진 (강남SE 모임) :: AWS Community Day 2017
 
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
AWS와 부하테스트의 절묘한 만남 :: 김무현 솔루션즈 아키텍트 :: Gaming on AWS 2016
 
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly
[오픈소스컨설팅]이기종 WAS 클러스터링 솔루션- Athena Dolly
 
Modern Incident Management with Atlassian (오픈소스컨설팅)
Modern Incident Management with Atlassian (오픈소스컨설팅)Modern Incident Management with Atlassian (오픈소스컨설팅)
Modern Incident Management with Atlassian (오픈소스컨설팅)
 
L4교육자료
L4교육자료L4교육자료
L4교육자료
 
Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부Fargate 를 이용한 ECS with VPC 1부
Fargate 를 이용한 ECS with VPC 1부
 
코드로 인프라 관리하기 - 자동화 툴 소개
코드로 인프라 관리하기 - 자동화 툴 소개코드로 인프라 관리하기 - 자동화 툴 소개
코드로 인프라 관리하기 - 자동화 툴 소개
 
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)
마이크로서비스 아키텍처와 DevOps 기술 - Amazon 사례를 중심으로 (윤석찬)
 
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar
AWS 활용하여 핀테크 신사업 시작하기 - 피플펀드 고객 사례 :: 지성국 :: AWS Finance Seminar
 
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
 
좌충우돌 Data Engineering 학습기
좌충우돌 Data Engineering 학습기좌충우돌 Data Engineering 학습기
좌충우돌 Data Engineering 학습기
 
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018
실전 프로젝트로 이야기하는 AWS IoT::김민성::AWS Summit Seoul 2018
 
Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용Twitter의 snowflake 소개 및 활용
Twitter의 snowflake 소개 및 활용
 
F5_Active-Active Data Center.pdf
F5_Active-Active Data Center.pdfF5_Active-Active Data Center.pdf
F5_Active-Active Data Center.pdf
 

Viewers also liked

Reducing Database Pain & Costs with Postgres
Reducing Database Pain & Costs with PostgresReducing Database Pain & Costs with Postgres
Reducing Database Pain & Costs with PostgresEDB
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns ReconsideredAlex Miller
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QAarchwisp
 
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiT
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiTComparing the Multimodal Interaction Technique Design of MINT with NiMMiT
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiTSebastian Feuerstack
 
Lca seminar modified
Lca seminar modifiedLca seminar modified
Lca seminar modifiedInbok Lee
 
Integrating Lucene into a Transactional XML Database
Integrating Lucene into a Transactional XML DatabaseIntegrating Lucene into a Transactional XML Database
Integrating Lucene into a Transactional XML Databaselucenerevolution
 
Gesture-aware remote controls: guidelines and interaction techniques
Gesture-aware remote controls: guidelines and interaction techniquesGesture-aware remote controls: guidelines and interaction techniques
Gesture-aware remote controls: guidelines and interaction techniquesDong-Bach Vo
 
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)Yusuke Iwasawa
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHPRob Knight
 
Masterizing php data structure 102
Masterizing php data structure 102Masterizing php data structure 102
Masterizing php data structure 102Patrick Allaert
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with PhingMichiel Rook
 
Semi supervised learning
Semi supervised learningSemi supervised learning
Semi supervised learningAhmed Taha
 
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...Spark Summit
 

Viewers also liked (20)

Why do I love and hate php?
Why do I love and hate php?Why do I love and hate php?
Why do I love and hate php?
 
Reducing Database Pain & Costs with Postgres
Reducing Database Pain & Costs with PostgresReducing Database Pain & Costs with Postgres
Reducing Database Pain & Costs with Postgres
 
Design Patterns Reconsidered
Design Patterns ReconsideredDesign Patterns Reconsidered
Design Patterns Reconsidered
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 
Fiksu Facebook report
Fiksu Facebook reportFiksu Facebook report
Fiksu Facebook report
 
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiT
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiTComparing the Multimodal Interaction Technique Design of MINT with NiMMiT
Comparing the Multimodal Interaction Technique Design of MINT with NiMMiT
 
Encoding survey
Encoding surveyEncoding survey
Encoding survey
 
Lca seminar modified
Lca seminar modifiedLca seminar modified
Lca seminar modified
 
Integrating Lucene into a Transactional XML Database
Integrating Lucene into a Transactional XML DatabaseIntegrating Lucene into a Transactional XML Database
Integrating Lucene into a Transactional XML Database
 
Gesture-aware remote controls: guidelines and interaction techniques
Gesture-aware remote controls: guidelines and interaction techniquesGesture-aware remote controls: guidelines and interaction techniques
Gesture-aware remote controls: guidelines and interaction techniques
 
Xml databases
Xml databasesXml databases
Xml databases
 
Algorithms and Data Structures~hmftj
Algorithms and Data Structures~hmftjAlgorithms and Data Structures~hmftj
Algorithms and Data Structures~hmftj
 
XML In My Database!
XML In My Database!XML In My Database!
XML In My Database!
 
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)
[DL Hacks輪読] Semi-Supervised Learning with Ladder Networks (NIPS2015)
 
XML Databases
XML DatabasesXML Databases
XML Databases
 
Object Relational Mapping in PHP
Object Relational Mapping in PHPObject Relational Mapping in PHP
Object Relational Mapping in PHP
 
Masterizing php data structure 102
Masterizing php data structure 102Masterizing php data structure 102
Masterizing php data structure 102
 
Building and deploying PHP applications with Phing
Building and deploying PHP applications with PhingBuilding and deploying PHP applications with Phing
Building and deploying PHP applications with Phing
 
Semi supervised learning
Semi supervised learningSemi supervised learning
Semi supervised learning
 
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...
Extending Word2Vec for Performance and Semi-Supervised Learning-(Michael Mala...
 

Similar to Singletons in PHP - Why they are bad and how you can eliminate them from your applications

Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingTricode (part of Dept)
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPmtoppa
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applicationschartjes
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICKonstantin Kudryashov
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCpootsbook
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodeSWIFTotter Solutions
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserHoward Lewis Ship
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injectionJosh Adell
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityWashington Botelho
 

Similar to Singletons in PHP - Why they are bad and how you can eliminate them from your applications (20)

Zend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching loggingZend framework 03 - singleton factory data mapper caching logging
Zend framework 03 - singleton factory data mapper caching logging
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Dependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHPDependency Inversion and Dependency Injection in PHP
Dependency Inversion and Dependency Injection in PHP
 
Building Testable PHP Applications
Building Testable PHP ApplicationsBuilding Testable PHP Applications
Building Testable PHP Applications
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Backbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVCBackbone.js — Introduction to client-side JavaScript MVC
Backbone.js — Introduction to client-side JavaScript MVC
 
PHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better CodePHP: 4 Design Patterns to Make Better Code
PHP: 4 Design Patterns to Make Better Code
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Backbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The BrowserBackbone.js: Run your Application Inside The Browser
Backbone.js: Run your Application Inside The Browser
 
Migrating to dependency injection
Migrating to dependency injectionMigrating to dependency injection
Migrating to dependency injection
 
Teste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrityTeste de Integração com DbUnit e jIntegrity
Teste de Integração com DbUnit e jIntegrity
 
Design patterns in PHP
Design patterns in PHPDesign patterns in PHP
Design patterns in PHP
 

Recently uploaded

Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...DianaGray10
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URLRuncy Oommen
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxUdaiappa Ramachandran
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsSafe Software
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7DianaGray10
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfAijun Zhang
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesMd Hossain Ali
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdfPedro Manuel
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioChristian Posta
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPathCommunity
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Commit University
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1DianaGray10
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAshyamraj55
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDELiveplex
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Will Schroeder
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaborationbruanjhuli
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Adtran
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureEric D. Schabell
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...Aggregage
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopBachir Benyammi
 

Recently uploaded (20)

Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
Connector Corner: Extending LLM automation use cases with UiPath GenAI connec...
 
Designing A Time bound resource download URL
Designing A Time bound resource download URLDesigning A Time bound resource download URL
Designing A Time bound resource download URL
 
Building AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptxBuilding AI-Driven Apps Using Semantic Kernel.pptx
Building AI-Driven Apps Using Semantic Kernel.pptx
 
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration WorkflowsIgniting Next Level Productivity with AI-Infused Data Integration Workflows
Igniting Next Level Productivity with AI-Infused Data Integration Workflows
 
UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7UiPath Studio Web workshop series - Day 7
UiPath Studio Web workshop series - Day 7
 
Machine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdfMachine Learning Model Validation (Aijun Zhang 2024).pdf
Machine Learning Model Validation (Aijun Zhang 2024).pdf
 
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just MinutesAI Fame Rush Review – Virtual Influencer Creation In Just Minutes
AI Fame Rush Review – Virtual Influencer Creation In Just Minutes
 
Nanopower In Semiconductor Industry.pdf
Nanopower  In Semiconductor Industry.pdfNanopower  In Semiconductor Industry.pdf
Nanopower In Semiconductor Industry.pdf
 
Comparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and IstioComparing Sidecar-less Service Mesh from Cilium and Istio
Comparing Sidecar-less Service Mesh from Cilium and Istio
 
UiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation DevelopersUiPath Community: AI for UiPath Automation Developers
UiPath Community: AI for UiPath Automation Developers
 
Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)Crea il tuo assistente AI con lo Stregatto (open source python framework)
Crea il tuo assistente AI con lo Stregatto (open source python framework)
 
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1UiPath Platform: The Backend Engine Powering Your Automation - Session 1
UiPath Platform: The Backend Engine Powering Your Automation - Session 1
 
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPAAnypoint Code Builder , Google Pub sub connector and MuleSoft RPA
Anypoint Code Builder , Google Pub sub connector and MuleSoft RPA
 
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDEADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
ADOPTING WEB 3 FOR YOUR BUSINESS: A STEP-BY-STEP GUIDE
 
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
Apres-Cyber - The Data Dilemma: Bridging Offensive Operations and Machine Lea...
 
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online CollaborationCOMPUTER 10: Lesson 7 - File Storage and Online Collaboration
COMPUTER 10: Lesson 7 - File Storage and Online Collaboration
 
Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™Meet the new FSP 3000 M-Flex800™
Meet the new FSP 3000 M-Flex800™
 
OpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability AdventureOpenShift Commons Paris - Choose Your Own Observability Adventure
OpenShift Commons Paris - Choose Your Own Observability Adventure
 
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
The Data Metaverse: Unpacking the Roles, Use Cases, and Tech Trends in Data a...
 
NIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 WorkshopNIST Cybersecurity Framework (CSF) 2.0 Workshop
NIST Cybersecurity Framework (CSF) 2.0 Workshop
 

Singletons in PHP - Why they are bad and how you can eliminate them from your applications

  • 1. Singletons in Why they are bad and how you can eliminate them from your applications
  • 2. Gordon Oheim @go_oh
  • 6. Creational Pattern „control when and how objects are created“
  • 7. “Ensure a class has only one instance, and provide a global access point to it.”
  • 8. Singleton Singleton - instance : Singleton - instance : Singleton + + getInstance() getInstance() : : Singleton Singleton - - __construct() __construct() : : void void - - __clone() __clone() : : void void - - __wakeup() __wakeup() : : void void
  • 9. class Singleton … public static function getInstance() { if (!isset(self::$instance)) { self::$instance = new self; } return self::$instance; } }
  • 10. abstract class Singleton … public static function getInstance() { return isset(static::$instance) ? static::$instance : static::$instance = new static; } final private function __construct() { static::init(); } protected function init() {} } class A extends Singleton { protected static $instance; }
  • 11. trait Singleton … protected static $instance; final public static function getInstance() { return isset(static::$instance) ? static::$instance : static::$instance = new static; } final private function __construct() { static::init(); } protected function init() {} } class A { use Singleton; }
  • 12. „Nobody should need a mechanism to make it as easy as pie to clutter the code base with singletons“ - Sebastian Bergmann
  • 14. „In my stilted view of the universe anything that impedes testing is something to be avoided. There are those who don't agree with this view, but I'll pit my defect rates against theirs any time.“ - Robert „Uncle Bob“ C. Martin
  • 15. class TableDataGateway … public function __construct() { $this->db = Db::getInstance(); } public insert(array $data) { $this->db->sql('INSERT …', $data); } }
  • 16. class TableDataGatewayTest extends PHPUnit… /** * @dataProvider provideInsertData */ public function testInsertCallsDbWithData($data) { $gateway = new TableDataGateway; $gateway->insert($data); $this->assertSame( $data, $gateway->findById($data['id']) ); } }
  • 17. throws LogicException: No key found for 'pdo' in Registry
  • 18. class Db extends Singleton … protected function init() { $this->logger = Logger::getInstance(); $this->pdo = new PDO(Registry::get('pdo')); } public sql($query, $data) { $this->logger->log(printf( 'Executed %s with %s', $query, implode(',', $data) )); $sth = $this->pdo->prepare($query); return $sth->execute($data); } }
  • 19. Singletons are pathological liars - Miško Hevery
  • 20. class TableDataGatewayTest extends PHPUnit… /** * @dataProvider provideInsertData */ public function testInsertCallsDbWithData($data) { Registry::set('pdo', array('…')); Registry::set('log', '/dev/null'); $gateway = new TableDataGateway; $gateway->insert($data); $this->assertSame( $data, $gateway->findById($data['id']) ); } }
  • 21. Your tests are not isolated. You still need a real database. No easy way to mock the Db Singleton.
  • 22. „The real problem with Singletons is that they give you such a good excuse not to think carefully about the appropriate visibility of an object.“ - Kent Beck
  • 23. Hard to change code manifests itself in a cascade of subsequent changes in dependent code
  • 24. Fragile code breaks in many places when you change just one place
  • 25. Non-reusable code is code that you cannot reuse in another project because it contains too much extra baggage
  • 27. Single Responsibility Principle A class should have one, and only one, reason to change.
  • 28. Open Closed Principle You should be able to extend a classes behavior, without modifying it.
  • 29. Liskov Substitution Principle Derived classes must be substitutable for their base classes.
  • 30. Interface Segregation Principle Make fine grained interfaces that are client specific.
  • 31. Dependency Inversion Principle Depend on abstractions, not on concretions.
  • 33. SRP Violation Creation Logic + Business Logic = 2 reasons to change Mitigated by using Abstract Singletons But responsibilities are still strongly coupled through inheritance
  • 34. OCP Violation In PHP < 5.2 Singletons are closed for extending Boilerplate code has to be removed when no longer needed
  • 35. DIP Violation Global access breaks encapsulation Hides dependencies Adds concrete dependencies into Clients Signature lies
  • 37. Config FooController Response FrontController ThatService Request Cache Database Application BarController Registry Logger ThisService Bootstrap Acl
  • 38. Config FooController Response FrontController ThatService Request Cache Database Application BarController Registry Logger ThisService Bootstrap Acl
  • 39. Recap: “Ensure a class has only one instance, and provide a global access point to it.”
  • 40. „So much of the Singleton pattern is about coaxing language protection mechanisms into protecting this one aspect: singularity. I guess it is important, but it seems to have grown out of proportion.“ - Ward Cunningham
  • 41. You do not need to ensure singularity when you are going to instantiate the object only once anyway.
  • 42. You do not need to provide a Global Access Point when you can inject the object.
  • 43. class TableDataGateway … public function __construct() { $this->db = Db::getInstance(); } } class Db extends Singleton … protected function init() { $this->logger = Logger::getInstance(); $this->pdo = new PDO(Registry::get('pdo')); } }
  • 44. class TableDataGateway … public function __construct(Db $db) { $this->db = $db; } } class Db … public function __construct(PDO $pdo, Log $logger) { $this->logger = $logger; $this->pdo = $pdo; } }
  • 45. But then I have to push dependencies all the way through my object graph?!
  • 46. Recap: Creational Pattern „control when and how objects are created“
  • 47. Use Builders and Factories to create Collaborator Graphs
  • 48. class UserControllerBuilder { public function build($config) { $log = new Log($config['log']); $pdo = new PDO($config['…']); $db = new Db($pdo, $log); $tdg = new TableDataGateway($db); return new UserController($tdg); } }
  • 49. class UserControllerBuilder { public function build($config) { $log = new Log($config['log']); $pdo = new PDO($config['…']); ??? $db = new Db($pdo, $log); $tdg = new TableDataGateway($db); return new UserController($tdg); } }
  • 50. class UserControllerBuilder { public function build($config) { $db = new LogDecorator( new PDO($config['…']); new Log($config['log']); ); $tdg = new TableDataGateway($db); return new UserController($tdg); } }
  • 51. // index.php include '/path/to/autoload.php'; $config = new Config('/path/to/config.ini'); $router = new Router( array( '/user/{id}' => function() use ($config) { $builder = new UserControllerBuilder; return $builder->build($config); } ) ); $router->route( new Request($_GET, $_POST, $_SERVER), new Response );
  • 52. „Singletons aren't necessary when you can design or redesign to avoid using them.“ - Joshua Kerievsky
  • 53. „I'm in favor of dropping Singleton. Its use is almost always a design smell“ - Erich Gamma