SlideShare a Scribd company logo
Separation of Concerns
Separation of concerns

 About Joshua

  Joshua Thijssen, NoxLogic / Techademy
  Freelance Consultant, Developer, Trainer
  Development in PHP, Python, Perl, C, Java
  jthijssen@noxlogic.nl
  @jaytaph
Separation of concerns

 About Stephan

  Stephan Hochdörfer, bitExpert AG
  Department Manager Research Labs
  enjoying PHP since 1999
  S.Hochdoerfer@bitExpert.de
  @shochdoerfer
Separation of concerns




 It is what I sometimes have called the
 separation of concerns, which [...] is
   yet the only available technique for
   effective ordering of one's thoughts.
     Edsger W. Dijkstra, "On the role of scientific thought" (1974)
Separation of concerns




   SoC […] is the process of breaking a
     computer program into distinct
   features that overlap in functionality
          as little as possible.
         http://en.wikipedia.org/wiki/Separation_of_concerns
Separation of concerns


 It`s all about focusing!
Separation of concerns




 One step a time. Focus on the details!
Separation of concerns

<?php
$items = array();
$token = file_get_contents("https://graph.facebook.com/oauth/access_token?...");
$feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token);
$feed = json_decode($feed, true);
foreach($feed['data'] as $post) {
  if('123456789012' === $post['from']['id']) {
    $items[] = array(
       'date' => strtotime($post['created_time']),
       'message' => $post['message']);
  }
}

$feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident");
$feed = json_decode($feed, true);
foreach($feed['results'] as $tweet) {
    $items[] = array(
       'date' => strtotime($tweet['created_at']),
       'message' => $tweet['text']);
}

foreach($items as $item) {
  echo $item['message'];
}
Separation of concerns

<?php                                                    Controller part!
$items = array();
$token = file_get_contents("https://graph.facebook.com/oauth/access_token?...");
$feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token);
$feed = json_decode($feed, true);
foreach($feed['data'] as $post) {
  if('123456789012' === $post['from']['id']) {
    $items[] = array(
       'date' => strtotime($post['created_time']),
       'message' => $post['message']);
  }
}

$feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident");
$feed = json_decode($feed, true);
foreach($feed['results'] as $tweet) {
    $items[] = array(
       'date' => strtotime($tweet['created_at']),
       'message' => $tweet['text']);
}

foreach($items as $item) {
  echo $item['message'];
}}
Separation of concerns

<?php
$items = array();
$token = file_get_contents("https://graph.facebook.com/oauth/access_token?...");
$feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token);
$feed = json_decode($feed, true);
foreach($feed['data'] as $post) {
  if('123456789012' === $post['from']['id']) {
    $items[] = array(
       'date' => strtotime($post['created_time']),
       'message' => $post['message']);
  }
}

$feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident");
$feed = json_decode($feed, true);
foreach($feed['results'] as $tweet) {
    $items[] = array(
       'date' => strtotime($tweet['created_at']),
       'message' => $tweet['text']);
}

foreach($items as $item) {
  echo $item['message'];
                                          View part!
}
Separation of concerns




 Very unstable. Not safe for changes....
Separation of concerns


 „Make everything as simple as possible...“
Separation of concerns




 Establish boundaries
Separation of concerns

 What are the boundaries?


                   Presentation Layer
Separation of concerns

 What are the boundaries?


                   Presentation Layer



                         Business Layer
Separation of concerns

 What are the boundaries?


                   Presentation Layer



                         Business Layer



                 Resource Access Layer
Separation of concerns




 Isolate functionality, break it apart!
Separation of concerns

<?php
namespace AcmeDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;

class DemoController extends Controller {
    /**
     * @Route("/", name="_demo")
     * @Template()
     */
    public function indexAction() {
    $items = array();
    $token = file_get_contents("https://graph.facebook.com/oauth/access_to...");
    $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token);
    $feed = json_decode($feed, true);
    foreach($feed['data'] as $post) {
      if('123456789012' === $post['from']['id']) {
        $items[] = array(
          'date' => strtotime($post['created_time']),
          'message' => $post['message']);
      }
    }
Separation of concerns

    $feed = file_get_contents("http://search.twitter.com/search.json?...");
    $feed = json_decode($feed, true);
    foreach($feed['results'] as $tweet) {
        $items[] = array(
          'date' => strtotime($tweet['created_at']),
          'message' => $tweet['text']);
    }

        return array('items' => $items);
    }
}
Separation of concerns




 Focus on one responsibility a time!
Separation of concerns

<?php
namespace AcmeDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;

class DemoController extends Controller {
    /**
     * @Route("/", name="_demo")
     * @Template()
     */
    public function indexAction() {
    $items = array();
                                                  Facebook connector
    $token = file_get_contents("https://graph.facebook.com/oauth/access_to...");
    $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token);
    $feed = json_decode($feed, true);
    foreach($feed['data'] as $post) {
      if('123456789012' === $post['from']['id']) {
        $items[] = array(
          'date' => strtotime($post['created_time']),
          'message' => $post['message']);
      }
    }
Separation of concerns



                                                 Twitter connector
    $feed = file_get_contents("http://search.twitter.com/search.json?...");
    $feed = json_decode($feed, true);
    foreach($feed['results'] as $tweet) {
        $items[] = array(
          'date' => strtotime($tweet['created_at']),
          'message' => $tweet['text']);
    }

    return array('items' => $items);
    }
}
Separation of concerns



 Interfaces as a contract
Separation of concerns

<?php
interface ConnectorInterface {
  /**
   * Will return an array of the latest posts.
   * return array
   */
  public function getLatestPosts() {
  }
}
Separation of concerns

<?php
class FacebookConnector implements ConnectorInterface {
  protected $handle;

    public function __construct($handle) {
      $this->handle = $handle;
    }

    public function getLatestPosts() {
      $items = array();
      $token = file_get_contents("https://graph.facebook.com/oauth/access...");
      $feed = file_get_contents("https://graph.facebook.com/.
           $this->handle."/feed?".$token);
      $feed = json_decode($feed, true);
      foreach($feed['data'] as $post) {
        if('123456789012' === $post['from']['id']) {
          $items[] = array(
          'date' => strtotime($post['created_time']),
          'message' => $post['message']);
        }
      }
      return $items;
    }
}
Separation of concerns

<?php
class FacebookConnector implements ConnectorInterface {
  protected $handle;

    public function __construct($handle) {
      $this->handle = $handle;
    }

    public function getLatestPosts() {
      $token = $this->getAccessToken();
      return $this->readPosts($token);
    }

    protected function getAccessToken() {
      return file_get_contents("https://graph.facebook.com/oauth/access_?...");
    }

    protected function readPosts($token) {
      // read the post, filter all relevant and return them...
    }
}
Separation of concerns

<?php
class FacebookConnectorV2 extends FacebookConnector {

    protected function getAccessToken() {
      return md5($this->handle);
    }
}




                Easy to extend, will not influence
                the behaviour of other methods!
Separation of concerns

<?php
namespace AcmeDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;

class DemoController extends Controller {
    /**
     * @Route("/", name="_demo")
     * @Template()
     */
    public function indexAction() {
    $items = array();
    $fb = $this->get('FbConnector');
    $items += $fb->getLatestPosts();

    $feed = file_get_contents("http://search.twitter.com/search.json?...");
    $feed = json_decode($feed, true);
    foreach($feed['results'] as $tweet) {
        $items[] = array(
          'date' => strtotime($tweet['created_at']),
          'message' => $tweet['text']);
    }
Separation of concerns

<?php
namespace AcmeDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
use SensioBundleFrameworkExtraBundleConfigurationTemplate;

class DemoController extends Controller {
    /**
     * @Route("/", name="_demo")
     * @Template()
     */
    public function indexAction() {
    $items = array();
    $fb = $this->get('FbConnector');
    $items += $fb->getLatestPosts();

    $twitter = $this->get('TwitterConnector');
    $items += $twitter->getLatestPosts();

     return array('items' => $items);
    }
}
Separation of concerns




 Will improve the testability!
Separation of concerns


 Will reduce tight coupling!
Separation of concerns




 Will increase component reuse!
Separation of concerns

 The value of separation




                Why should I do it?
Separation of concerns

 The value of separation




      1. Getting rid of code duplication
Separation of concerns

 The value of separation




   2. Application becomes more stable
        and easier to understand
Separation of concerns

 The value of separation




    3. Single responsibility offers clear
              extension points
Separation of concerns

 The value of separation




        4. Increases the reusability of
                 components
Separation of concerns




 How to separate the concerns?
Separation of concerns

 How to separate? Horizontal Separation


                   Presentation Layer



                         Business Layer



                 Resource Access Layer
Separation of concerns

 How to separate? Horizontal Separation
 ./symfony
    |-app
    |---cache
    |---config
    |---Resources
    |-src
    |---Acme
    |-----DemoBundle
    |-------Controller
    |-------Resources
    |---------config
    |---------public
    |-----------css
    |-----------images
    |---------views
    |-----------Demo
    |-----------Welcome
    |-------Tests
    |---------Controller
    |-web
Separation of concerns

 How to separate? Service Separation


                 Service Interface Layer



                         Business Layer



                 Resource Access Layer
Separation of concerns

 How to separate? Service Separation

                Frontend / UI Webservers




            REST API         Solr Search Service




           Datastore
Separation of concerns

 How to separate? Vertical Separation




        Module A         Module B   Module C
Separation of concerns

 How to separate? Vertical Separation
 ./symfony
    |-app
    |---cache
    |---config
    |---Resources
    |-src
    |---Acme
    |-----AdminBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-----ProductsBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-----CustomersBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-web
Separation of concerns

 How to separate? Vertical Separation


       Presentation      Presentation   Presentation
          Layer             Layer          Layer



        Business          Business       Business
         Layer             Layer          Layer



        Resource          Resource       Resource
       Access Layer      Access Layer   Access Layer
Separation of concerns

 How to separate? Vertical Separation
 ./symfony
    |-app
    |---cache
    |---config
    |---Resources
    |-src
    |---Acme
    |-----AdminBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-----ProductsBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-----CustomersBundle
    |-------Controller
    |-------Resources
    |-------Tests
    |-web
Separation of concerns

 Cross-cutting concerns?




     How to deal with security or logging
                  aspects?
Separation of concerns

 How to separate? Aspect Separation

 Aspects
                         Presentation Layer



                          Business Layer



                   Resource Access Layer
Separation of concerns

 How to separate? Aspect Separation
 <?php
 namespace AcmeProductsAspects;

 /**
  * @FLOW3Aspect
  */
 class LoggingAspect {
         /**
          * @FLOW3Inject
          * @var AcmeLoggerLoggerInterface
          */
         protected $logger;

         /**
          * @param TYPO3FLOW3AOPJoinPointInterface $joinPoint
          * @FLOW3Before("method(AcmeProductsModelProduct->delete())")
          */
         public function log(TYPO3FLOW3AOPJoinPointInterface $jp) {
                 $product = $jp->getMethodArgument('product');
                 $this->logger->info('Removing ' .
                  $product->getName());
         }
 }
Separation of concerns



 Dependency Direction
Separation of concerns

 Dependency Direction


        "High-level modules should not
         depend on low-level modules.
            Both should depend on
                 abstractions."
                         Robert C. Martin
Separation of concerns

 Inverting Concerns


       Presentation
          Layer



        Business
         Layer



        Resource
       Access Layer
Separation of concerns

 Inverting Concerns


       Presentation      UI     Presentation
          Layer       Component    Layer



        Business                 Business
         Layer                    Layer



        Resource                Resource
       Access Layer            Access Layer
Separation of concerns

 Inverting Concerns


      The goal of Dependency Injection
        is to separate the concerns of
       obtaining the dependencies from
      the core concerns of a component.
Separation of concerns

 What are the benefits? Let`s recap....
Separation of concerns

 What are the benefits?




             1. Facilitate reusability
Separation of concerns

 What are the benefits?




        2. Ensure the maintainability
Separation of concerns

 What are the benefits?




        3. Increasing the code quality
Separation of concerns

 What are the benefits?




   4. Enables everyone to understand
             the application
Separation of concerns

 What are the benefits?




        5. Allows developers to work
         on components in isolation
Thank you!
http://joind.in/6244

More Related Content

PPTX
REST API Design & Development
PPT
Understanding REST
PPTX
PPT
Introduction to the Web API
PDF
JavaScript Basics and Best Practices - CC FE & UX
PPTX
ASP.NET Page Life Cycle
PPTX
Introduction to php
REST API Design & Development
Understanding REST
Introduction to the Web API
JavaScript Basics and Best Practices - CC FE & UX
ASP.NET Page Life Cycle
Introduction to php

What's hot (20)

PDF
Clean Architecture Applications in Python
PDF
Spring Data JPA
PPT
Ppt of soap ui
PPTX
Introduction to ASP.NET
PPT
Service Oriented Architecture
PDF
Microservices and SOA
PPTX
Asp.net MVC training session
PDF
What is REST API? REST API Concepts and Examples | Edureka
PPTX
Sling models by Justin Edelson
PDF
Modern Web Development
PPTX
Microservice vs. Monolithic Architecture
PDF
Dot Net Core
PDF
Api pattern
PPTX
Rest presentation
PPTX
Rest assured
PDF
A Separation of Concerns: Clean Architecture on Android
PPTX
Advance Java Topics (J2EE)
PDF
Laravel - The PHP Framework for Web Artisans
PPTX
Creation of cloud application using microsoft azure by vaishali sahare [katkar]
PPTX
Type script - advanced usage and practices
Clean Architecture Applications in Python
Spring Data JPA
Ppt of soap ui
Introduction to ASP.NET
Service Oriented Architecture
Microservices and SOA
Asp.net MVC training session
What is REST API? REST API Concepts and Examples | Edureka
Sling models by Justin Edelson
Modern Web Development
Microservice vs. Monolithic Architecture
Dot Net Core
Api pattern
Rest presentation
Rest assured
A Separation of Concerns: Clean Architecture on Android
Advance Java Topics (J2EE)
Laravel - The PHP Framework for Web Artisans
Creation of cloud application using microsoft azure by vaishali sahare [katkar]
Type script - advanced usage and practices
Ad

Similar to Separation of concerns - DPC12 (20)

PDF
Virtual Madness @ Etsy
KEY
Introducing CakeEntity
KEY
Unit testing zend framework apps
KEY
Unit testing with zend framework PHPBenelux
PDF
Unit testing with zend framework tek11
PDF
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
KEY
Introducing CakeEntity
PDF
Lithium: The Framework for People Who Hate Frameworks
KEY
Symfony2 Building on Alpha / Beta technology
PPTX
HirshHorn theme: how I created it
KEY
jQuery: Tips, tricks and hints for better development and Performance
PDF
international PHP2011_Bastian Feder_jQuery's Secrets
PDF
Hooks WCSD12
PDF
jQuery secrets
PDF
Migrare da symfony 1 a Symfony2
PDF
[WLDN] Supercharging word press development in 2018
PDF
Unittests für Dummies
PDF
jQuery secrets
KEY
Lithium Best
PPTX
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Virtual Madness @ Etsy
Introducing CakeEntity
Unit testing zend framework apps
Unit testing with zend framework PHPBenelux
Unit testing with zend framework tek11
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Introducing CakeEntity
Lithium: The Framework for People Who Hate Frameworks
Symfony2 Building on Alpha / Beta technology
HirshHorn theme: how I created it
jQuery: Tips, tricks and hints for better development and Performance
international PHP2011_Bastian Feder_jQuery's Secrets
Hooks WCSD12
jQuery secrets
Migrare da symfony 1 a Symfony2
[WLDN] Supercharging word press development in 2018
Unittests für Dummies
jQuery secrets
Lithium Best
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Ad

More from Stephan Hochdörfer (20)

PDF
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
PDF
Phing for power users - frOSCon8
PDF
Offline strategies for HTML5 web applications - frOSCon8
PDF
Offline Strategies for HTML5 Web Applications - oscon13
PDF
Real World Dependency Injection - oscon13
PDF
Dependency Injection in PHP - dwx13
PDF
Offline Strategien für HTML5 Web Applikationen - dwx13
PDF
Your Business. Your Language. Your Code - dpc13
PDF
Phing for power users - dpc_uncon13
PDF
Offline Strategies for HTML5 Web Applications - ipc13
PDF
Offline-Strategien für HTML5 Web Applikationen - wmka
PDF
Offline-Strategien für HTML5 Web Applikationen - bedcon13
PDF
Real World Dependency Injection - phpugffm13
PDF
Testing untestable code - ConFoo13
PDF
A Phing fairy tale - ConFoo13
PDF
Offline strategies for HTML5 web applications - ConFoo13
PDF
Offline-Strategien für HTML5Web Applikationen - WMMRN12
PDF
Testing untestable code - IPC12
PDF
Offline strategies for HTML5 web applications - IPC12
PDF
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Phing for power users - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
Offline Strategies for HTML5 Web Applications - oscon13
Real World Dependency Injection - oscon13
Dependency Injection in PHP - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13
Your Business. Your Language. Your Code - dpc13
Phing for power users - dpc_uncon13
Offline Strategies for HTML5 Web Applications - ipc13
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Real World Dependency Injection - phpugffm13
Testing untestable code - ConFoo13
A Phing fairy tale - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Testing untestable code - IPC12
Offline strategies for HTML5 web applications - IPC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12

Recently uploaded (20)

PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Cloud computing and distributed systems.
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Network Security Unit 5.pdf for BCA BBA.
PPT
Teaching material agriculture food technology
PDF
Modernizing your data center with Dell and AMD
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Mobile App Security Testing_ A Comprehensive Guide.pdf
The Rise and Fall of 3GPP – Time for a Sabbatical?
Unlocking AI with Model Context Protocol (MCP)
Chapter 3 Spatial Domain Image Processing.pdf
NewMind AI Monthly Chronicles - July 2025
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Reach Out and Touch Someone: Haptics and Empathic Computing
Advanced methodologies resolving dimensionality complications for autism neur...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
NewMind AI Weekly Chronicles - August'25 Week I
MYSQL Presentation for SQL database connectivity
Cloud computing and distributed systems.
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Digital-Transformation-Roadmap-for-Companies.pptx
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Per capita expenditure prediction using model stacking based on satellite ima...
Network Security Unit 5.pdf for BCA BBA.
Teaching material agriculture food technology
Modernizing your data center with Dell and AMD

Separation of concerns - DPC12

  • 2. Separation of concerns About Joshua  Joshua Thijssen, NoxLogic / Techademy  Freelance Consultant, Developer, Trainer  Development in PHP, Python, Perl, C, Java  jthijssen@noxlogic.nl  @jaytaph
  • 3. Separation of concerns About Stephan  Stephan Hochdörfer, bitExpert AG  Department Manager Research Labs  enjoying PHP since 1999  S.Hochdoerfer@bitExpert.de  @shochdoerfer
  • 4. Separation of concerns It is what I sometimes have called the separation of concerns, which [...] is yet the only available technique for effective ordering of one's thoughts. Edsger W. Dijkstra, "On the role of scientific thought" (1974)
  • 5. Separation of concerns SoC […] is the process of breaking a computer program into distinct features that overlap in functionality as little as possible. http://en.wikipedia.org/wiki/Separation_of_concerns
  • 6. Separation of concerns It`s all about focusing!
  • 7. Separation of concerns One step a time. Focus on the details!
  • 8. Separation of concerns <?php $items = array(); $token = file_get_contents("https://graph.facebook.com/oauth/access_token?..."); $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } } $feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident"); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); } foreach($items as $item) { echo $item['message']; }
  • 9. Separation of concerns <?php Controller part! $items = array(); $token = file_get_contents("https://graph.facebook.com/oauth/access_token?..."); $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } } $feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident"); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); } foreach($items as $item) { echo $item['message']; }}
  • 10. Separation of concerns <?php $items = array(); $token = file_get_contents("https://graph.facebook.com/oauth/access_token?..."); $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } } $feed = file_get_contents("http://search.twitter.com/search.json?q=from:ident"); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); } foreach($items as $item) { echo $item['message']; View part! }
  • 11. Separation of concerns Very unstable. Not safe for changes....
  • 12. Separation of concerns „Make everything as simple as possible...“
  • 13. Separation of concerns Establish boundaries
  • 14. Separation of concerns What are the boundaries? Presentation Layer
  • 15. Separation of concerns What are the boundaries? Presentation Layer Business Layer
  • 16. Separation of concerns What are the boundaries? Presentation Layer Business Layer Resource Access Layer
  • 17. Separation of concerns Isolate functionality, break it apart!
  • 18. Separation of concerns <?php namespace AcmeDemoBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class DemoController extends Controller { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { $items = array(); $token = file_get_contents("https://graph.facebook.com/oauth/access_to..."); $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } }
  • 19. Separation of concerns $feed = file_get_contents("http://search.twitter.com/search.json?..."); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); } return array('items' => $items); } }
  • 20. Separation of concerns Focus on one responsibility a time!
  • 21. Separation of concerns <?php namespace AcmeDemoBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class DemoController extends Controller { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { $items = array(); Facebook connector $token = file_get_contents("https://graph.facebook.com/oauth/access_to..."); $feed = file_get_contents("https://graph.facebook.com/ident/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } }
  • 22. Separation of concerns Twitter connector $feed = file_get_contents("http://search.twitter.com/search.json?..."); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); } return array('items' => $items); } }
  • 23. Separation of concerns Interfaces as a contract
  • 24. Separation of concerns <?php interface ConnectorInterface { /** * Will return an array of the latest posts. * return array */ public function getLatestPosts() { } }
  • 25. Separation of concerns <?php class FacebookConnector implements ConnectorInterface { protected $handle; public function __construct($handle) { $this->handle = $handle; } public function getLatestPosts() { $items = array(); $token = file_get_contents("https://graph.facebook.com/oauth/access..."); $feed = file_get_contents("https://graph.facebook.com/. $this->handle."/feed?".$token); $feed = json_decode($feed, true); foreach($feed['data'] as $post) { if('123456789012' === $post['from']['id']) { $items[] = array( 'date' => strtotime($post['created_time']), 'message' => $post['message']); } } return $items; } }
  • 26. Separation of concerns <?php class FacebookConnector implements ConnectorInterface { protected $handle; public function __construct($handle) { $this->handle = $handle; } public function getLatestPosts() { $token = $this->getAccessToken(); return $this->readPosts($token); } protected function getAccessToken() { return file_get_contents("https://graph.facebook.com/oauth/access_?..."); } protected function readPosts($token) { // read the post, filter all relevant and return them... } }
  • 27. Separation of concerns <?php class FacebookConnectorV2 extends FacebookConnector { protected function getAccessToken() { return md5($this->handle); } } Easy to extend, will not influence the behaviour of other methods!
  • 28. Separation of concerns <?php namespace AcmeDemoBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class DemoController extends Controller { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { $items = array(); $fb = $this->get('FbConnector'); $items += $fb->getLatestPosts(); $feed = file_get_contents("http://search.twitter.com/search.json?..."); $feed = json_decode($feed, true); foreach($feed['results'] as $tweet) { $items[] = array( 'date' => strtotime($tweet['created_at']), 'message' => $tweet['text']); }
  • 29. Separation of concerns <?php namespace AcmeDemoBundleController; use SymfonyBundleFrameworkBundleControllerController; use SensioBundleFrameworkExtraBundleConfigurationRoute; use SensioBundleFrameworkExtraBundleConfigurationTemplate; class DemoController extends Controller { /** * @Route("/", name="_demo") * @Template() */ public function indexAction() { $items = array(); $fb = $this->get('FbConnector'); $items += $fb->getLatestPosts(); $twitter = $this->get('TwitterConnector'); $items += $twitter->getLatestPosts(); return array('items' => $items); } }
  • 30. Separation of concerns Will improve the testability!
  • 31. Separation of concerns Will reduce tight coupling!
  • 32. Separation of concerns Will increase component reuse!
  • 33. Separation of concerns The value of separation Why should I do it?
  • 34. Separation of concerns The value of separation 1. Getting rid of code duplication
  • 35. Separation of concerns The value of separation 2. Application becomes more stable and easier to understand
  • 36. Separation of concerns The value of separation 3. Single responsibility offers clear extension points
  • 37. Separation of concerns The value of separation 4. Increases the reusability of components
  • 38. Separation of concerns How to separate the concerns?
  • 39. Separation of concerns How to separate? Horizontal Separation Presentation Layer Business Layer Resource Access Layer
  • 40. Separation of concerns How to separate? Horizontal Separation ./symfony |-app |---cache |---config |---Resources |-src |---Acme |-----DemoBundle |-------Controller |-------Resources |---------config |---------public |-----------css |-----------images |---------views |-----------Demo |-----------Welcome |-------Tests |---------Controller |-web
  • 41. Separation of concerns How to separate? Service Separation Service Interface Layer Business Layer Resource Access Layer
  • 42. Separation of concerns How to separate? Service Separation Frontend / UI Webservers REST API Solr Search Service Datastore
  • 43. Separation of concerns How to separate? Vertical Separation Module A Module B Module C
  • 44. Separation of concerns How to separate? Vertical Separation ./symfony |-app |---cache |---config |---Resources |-src |---Acme |-----AdminBundle |-------Controller |-------Resources |-------Tests |-----ProductsBundle |-------Controller |-------Resources |-------Tests |-----CustomersBundle |-------Controller |-------Resources |-------Tests |-web
  • 45. Separation of concerns How to separate? Vertical Separation Presentation Presentation Presentation Layer Layer Layer Business Business Business Layer Layer Layer Resource Resource Resource Access Layer Access Layer Access Layer
  • 46. Separation of concerns How to separate? Vertical Separation ./symfony |-app |---cache |---config |---Resources |-src |---Acme |-----AdminBundle |-------Controller |-------Resources |-------Tests |-----ProductsBundle |-------Controller |-------Resources |-------Tests |-----CustomersBundle |-------Controller |-------Resources |-------Tests |-web
  • 47. Separation of concerns Cross-cutting concerns? How to deal with security or logging aspects?
  • 48. Separation of concerns How to separate? Aspect Separation Aspects Presentation Layer Business Layer Resource Access Layer
  • 49. Separation of concerns How to separate? Aspect Separation <?php namespace AcmeProductsAspects; /** * @FLOW3Aspect */ class LoggingAspect { /** * @FLOW3Inject * @var AcmeLoggerLoggerInterface */ protected $logger; /** * @param TYPO3FLOW3AOPJoinPointInterface $joinPoint * @FLOW3Before("method(AcmeProductsModelProduct->delete())") */ public function log(TYPO3FLOW3AOPJoinPointInterface $jp) { $product = $jp->getMethodArgument('product'); $this->logger->info('Removing ' . $product->getName()); } }
  • 50. Separation of concerns Dependency Direction
  • 51. Separation of concerns Dependency Direction "High-level modules should not depend on low-level modules. Both should depend on abstractions." Robert C. Martin
  • 52. Separation of concerns Inverting Concerns Presentation Layer Business Layer Resource Access Layer
  • 53. Separation of concerns Inverting Concerns Presentation UI Presentation Layer Component Layer Business Business Layer Layer Resource Resource Access Layer Access Layer
  • 54. Separation of concerns Inverting Concerns The goal of Dependency Injection is to separate the concerns of obtaining the dependencies from the core concerns of a component.
  • 55. Separation of concerns What are the benefits? Let`s recap....
  • 56. Separation of concerns What are the benefits? 1. Facilitate reusability
  • 57. Separation of concerns What are the benefits? 2. Ensure the maintainability
  • 58. Separation of concerns What are the benefits? 3. Increasing the code quality
  • 59. Separation of concerns What are the benefits? 4. Enables everyone to understand the application
  • 60. Separation of concerns What are the benefits? 5. Allows developers to work on components in isolation