Separation of concerns - DPC12
Upcoming SlideShare
Loading in...5
×
 

Separation of concerns - DPC12

on

  • 1,886 views

 

Statistics

Views

Total Views
1,886
Views on SlideShare
1,876
Embed Views
10

Actions

Likes
0
Downloads
11
Comments
0

2 Embeds 10

http://lanyrd.com 9
http://symfony2developer.com 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Separation of concerns - DPC12 Separation of concerns - DPC12 Presentation Transcript

  • 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 ones 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<?phpnamespace 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<?phpnamespace 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<?phpinterface ConnectorInterface { /** * Will return an array of the latest posts. * return array */ public function getLatestPosts() { }}
  • Separation of concerns<?phpclass 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<?phpclass 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<?phpclass FacebookConnectorV2 extends FacebookConnector { protected function getAccessToken() { return md5($this->handle); }} Easy to extend, will not influence the behaviour of other methods!
  • Separation of concerns<?phpnamespace 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<?phpnamespace 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