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

What's hot

Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
Badoo
 
Spring boot
Spring bootSpring boot
Spring boot
Pradeep Shanmugam
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
José Paumard
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
Rasheed Waraich
 
Understanding MicroSERVICE Architecture with Java & Spring Boot
Understanding MicroSERVICE Architecture with Java & Spring BootUnderstanding MicroSERVICE Architecture with Java & Spring Boot
Understanding MicroSERVICE Architecture with Java & Spring Boot
Kashif Ali Siddiqui
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
Joshua Long
 
Le Wagon - UI components design
Le Wagon - UI components designLe Wagon - UI components design
Le Wagon - UI components design
Boris Paillard
 
Techical Workflow for a Startup
Techical Workflow for a StartupTechical Workflow for a Startup
Techical Workflow for a Startup
Sébastien Saunier
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced JavascriptAdieu
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
Designveloper
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
Xcat Liu
 
Vuex
VuexVuex
jQuery
jQueryjQuery
가상화된 코드를 분석해보자
가상화된 코드를 분석해보자가상화된 코드를 분석해보자
가상화된 코드를 분석해보자
dkswognsdi
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett Welson
 
Refactoring for Domain Driven Design
Refactoring for Domain Driven DesignRefactoring for Domain Driven Design
Refactoring for Domain Driven Design
David Berliner
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
Jeevesh Pandey
 
Introduction to thymeleaf
Introduction to thymeleafIntroduction to thymeleaf
Introduction to thymeleaf
NexThoughts Technologies
 

What's hot (20)

Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Spring boot
Spring bootSpring boot
Spring boot
 
Spring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutesSpring Data JPA from 0-100 in 60 minutes
Spring Data JPA from 0-100 in 60 minutes
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
Understanding MicroSERVICE Architecture with Java & Spring Boot
Understanding MicroSERVICE Architecture with Java & Spring BootUnderstanding MicroSERVICE Architecture with Java & Spring Boot
Understanding MicroSERVICE Architecture with Java & Spring Boot
 
REST APIs with Spring
REST APIs with SpringREST APIs with Spring
REST APIs with Spring
 
Le Wagon - UI components design
Le Wagon - UI components designLe Wagon - UI components design
Le Wagon - UI components design
 
Techical Workflow for a Startup
Techical Workflow for a StartupTechical Workflow for a Startup
Techical Workflow for a Startup
 
Advanced Javascript
Advanced JavascriptAdvanced Javascript
Advanced Javascript
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
 
Vuex
VuexVuex
Vuex
 
jQuery
jQueryjQuery
jQuery
 
가상화된 코드를 분석해보자
가상화된 코드를 분석해보자가상화된 코드를 분석해보자
가상화된 코드를 분석해보자
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Refactoring for Domain Driven Design
Refactoring for Domain Driven DesignRefactoring for Domain Driven Design
Refactoring for Domain Driven Design
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Introduction to thymeleaf
Introduction to thymeleafIntroduction to thymeleaf
Introduction to thymeleaf
 

Similar to Separation of concerns - DPC12

Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
Nishan Subedi
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
Basuke Suzuki
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011camp_drupal_ua
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
Basuke Suzuki
 
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
Nate Abele
 
Symfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
HirshHorn theme: how I created it
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
Paul Bearne
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
Jonas De Smet
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretssmueller_sandsmedia
 
Hooks WCSD12
Hooks WCSD12Hooks WCSD12
Hooks WCSD12
Jeffrey Zinn
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
Adam Tomat
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
Lars Jankowfsky
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Balázs Tatár
 

Similar to Separation of concerns - DPC12 (20)

Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
Nickolay Shmalenuk.Render api eng.DrupalCamp Kyiv 2011
 
Introducing CakeEntity
Introducing CakeEntityIntroducing CakeEntity
Introducing CakeEntity
 
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 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technologySymfony2 Building on Alpha / Beta technology
Symfony2 Building on Alpha / Beta technology
 
HirshHorn theme: how I created it
HirshHorn theme: how I created itHirshHorn theme: how I created it
HirshHorn theme: how I created it
 
jQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and PerformancejQuery: Tips, tricks and hints for better development and Performance
jQuery: Tips, tricks and hints for better development and Performance
 
international PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secretsinternational PHP2011_Bastian Feder_jQuery's Secrets
international PHP2011_Bastian Feder_jQuery's Secrets
 
Hooks WCSD12
Hooks WCSD12Hooks WCSD12
Hooks WCSD12
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Migrare da symfony 1 a Symfony2
 Migrare da symfony 1 a Symfony2  Migrare da symfony 1 a Symfony2
Migrare da symfony 1 a Symfony2
 
[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018[WLDN] Supercharging word press development in 2018
[WLDN] Supercharging word press development in 2018
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
Lithium Best
Lithium Best Lithium Best
Lithium Best
 
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018Let's write secure Drupal code! - DrupalCamp Oslo, 2018
Let's write secure Drupal code! - DrupalCamp Oslo, 2018
 

More from Stephan Hochdörfer

Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Stephan Hochdörfer
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Stephan Hochdörfer
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Stephan Hochdörfer
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Stephan Hochdörfer
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Stephan Hochdörfer
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Stephan Hochdörfer
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Stephan Hochdörfer
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Stephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaStephan Hochdörfer
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Stephan Hochdörfer
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Stephan Hochdörfer
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Stephan Hochdörfer
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Stephan Hochdörfer
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Stephan Hochdörfer
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Stephan Hochdörfer
 

More from Stephan Hochdörfer (20)

Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
Offline. Na und? Strategien für offlinefähige Applikationen in HTML5 - Herbst...
 
Phing for power users - frOSCon8
Phing for power users - frOSCon8Phing for power users - frOSCon8
Phing for power users - frOSCon8
 
Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8Offline strategies for HTML5 web applications - frOSCon8
Offline strategies for HTML5 web applications - frOSCon8
 
Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13Offline Strategies for HTML5 Web Applications - oscon13
Offline Strategies for HTML5 Web Applications - oscon13
 
Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13Real World Dependency Injection - oscon13
Real World Dependency Injection - oscon13
 
Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13Dependency Injection in PHP - dwx13
Dependency Injection in PHP - dwx13
 
Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13 Offline Strategien für HTML5 Web Applikationen - dwx13
Offline Strategien für HTML5 Web Applikationen - dwx13
 
Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13Your Business. Your Language. Your Code - dpc13
Your Business. Your Language. Your Code - dpc13
 
Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13Phing for power users - dpc_uncon13
Phing for power users - dpc_uncon13
 
Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13Offline Strategies for HTML5 Web Applications - ipc13
Offline Strategies for HTML5 Web Applications - ipc13
 
Offline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmkaOffline-Strategien für HTML5 Web Applikationen - wmka
Offline-Strategien für HTML5 Web Applikationen - wmka
 
Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13Offline-Strategien für HTML5 Web Applikationen - bedcon13
Offline-Strategien für HTML5 Web Applikationen - bedcon13
 
Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13Real World Dependency Injection - phpugffm13
Real World Dependency Injection - phpugffm13
 
Testing untestable code - ConFoo13
Testing untestable code - ConFoo13Testing untestable code - ConFoo13
Testing untestable code - ConFoo13
 
A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13A Phing fairy tale - ConFoo13
A Phing fairy tale - ConFoo13
 
Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13Offline strategies for HTML5 web applications - ConFoo13
Offline strategies for HTML5 web applications - ConFoo13
 
Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12Offline-Strategien für HTML5Web Applikationen - WMMRN12
Offline-Strategien für HTML5Web Applikationen - WMMRN12
 
Testing untestable code - IPC12
Testing untestable code - IPC12Testing untestable code - IPC12
Testing untestable code - IPC12
 
Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12Offline strategies for HTML5 web applications - IPC12
Offline strategies for HTML5 web applications - IPC12
 
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
Große Systeme, lose Kopplung, Spaß bei der Arbeit! - WDC12
 

Recently uploaded

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 

Recently uploaded (20)

Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 

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