Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Service layer

6,883 views

Published on

Apresentação feita no Latinoware 2010 expondo o problema da arquitetura MVC e como solucionar utilizando de uma Camada de Serviços de Aplicação (Application Service Layer), bem como um exemplo real de utilização

Published in: Technology

Service layer

  1. 1. Guilherme Blanco Service Layer no PHP 5.3 Guilherme Blanco – Yahoo!
  2. 2. Guilherme Blanco Guilherme Blanco ● 10+ anos como desenvolvedor ● Evangelista Open Source ● Trabalha para Yahoo! ● Contribui para Doctrine, Zend Framework, Symfony e PHP ● No Twitter: @guilhermeblanco ● No GitHub: http://github.com/guilhermeblanco
  3. 3. Guilherme Blanco Arquitetura em camadas Service Layer no PHP 5.3
  4. 4. Guilherme Blanco Service Layer no PHP 5.3 “O padrão arquitetural em Camadas (Layers) ajuda a estruturar aplicações que podem ser decompostas em grupos de sub-tarefas no qual cada grupo está em um nível particular de abstração” Pattern-Oriented Software Architecture Volume 1: A System of Patterns
  5. 5. Guilherme Blanco Service Layer no PHP 5.3 Model-View-Controller (MVC)
  6. 6. Guilherme Blanco Service Layer no PHP 5.3 “I created the Model-View-Controller pattern as an obvious solution to the general problem of giving users control over their information as seen from multiple perspectives.” Trygve Reenskaug, http://heim.ifi.uio.no/~trygver/
  7. 7. Guilherme Blanco Service Layer no PHP 5.3 MODELMODELVIEWVIEW CONTROLLERCONTROLLER O bserva Observa O btém dados M odifica Obtém dados
  8. 8. Guilherme Blanco Service Layer no PHP 5.3 Delegando responsabilidades
  9. 9. Guilherme Blanco Service Layer no PHP 5.3 Model
  10. 10. Guilherme Blanco Service Layer no PHP 5.3 A ação de mover uma cadeira, faz parte da cadeira, de quem movimenta a cadeira ou outra coisa? Faz parte das ações da cadeira (ou seja, outra coisa)
  11. 11. Guilherme Blanco Service Layer no PHP 5.3 Como fazer para lidar com visualização de dados em múltiplos formatos (XML, JSON, HTML)? No Controller lide com o formato requisitado e delegue a renderização para a View correspondente
  12. 12. Guilherme Blanco Domain Model Service Layer no PHP 5.3 ● Tweetable “Modelo de Domínio é composto principalemente de Objeto de Domínio + Repositório. #latinoware” “Objeto de Domínio não devel conter ações sobre o próprio; Repositórios devem fazer isto. #latinoware” Domain ObjectRepository
  13. 13. Guilherme Blanco Service Layer no PHP 5.3 View
  14. 14. Guilherme Blanco Service Layer no PHP 5.3 Controller
  15. 15. Guilherme Blanco Service Layer no PHP 5.3 Perguntas?
  16. 16. Guilherme Blanco Service Layer no PHP 5.3 O que fazer quando a Business Layer precisa ser duplicada (web, api, mobile)? Precisamos de uma Application Service Layer
  17. 17. Guilherme Blanco Service Layer
  18. 18. Guilherme Blanco Service Layer no PHP 5.3
  19. 19. Guilherme Blanco No Model-Service-View-Controller, o Controller não pode acessar o Model Service Layer no PHP 5.3
  20. 20. Guilherme Blanco Service Layer no PHP 5.3 No Model-Service-View-Controller, Serviço é quem acessa Model
  21. 21. Guilherme Blanco Service Layer no PHP 5.3 Serviços podem chamar outros Serviços
  22. 22. Guilherme Blanco Service Layer no PHP 5.3 Injetar opções de configuração num dado Serviço
  23. 23. Guilherme Blanco Service Layer no PHP 5.3 Diferentes contextos de localização de Serviços
  24. 24. Guilherme Blanco Service Layer no PHP 5.3 Estratégias de carga de Serviços
  25. 25. Guilherme Blanco Service Layer no PHP 5.3 http://github.com/guilhermeblanco/ZF1-Doctrine2-ServiceLayer https://github.com/guilhermeblanco/ZendFramework1-Doctrine2
  26. 26. Guilherme Blanco Service Layer no PHP 5.3 Nosso problema: Lidar com a criação de um usuário
  27. 27. Guilherme Blanco Service Layer no PHP 5.3 namespace ApplicationEntity; /**  * @Entity(repositoryClass="ApplicationEntityRepositoryUserRepository")  * @Table(name="users")  */ class User {     /**      * @Id @GeneratedValue      * @Column(type="bigint")      * @var integer      */     protected $id;     /**      * @Column(type="string", length=200)      * @var string      */     protected $name;     /**      * @Column(type="string", length=200)      * @var string      */     protected $email;     /**      * @Column(type="string", length=50)      * @var string      */     protected $password; }
  28. 28. Guilherme Blanco Service Layer no PHP 5.3 namespace ApplicationEntityRepository; use DoctrineORMEntityRepository,     ApplicationEntityUser; /**  * UserRepository  *  * This class was generated by the Doctrine ORM. Add your own custom  * repository methods below.  */ class UserRepository extends EntityRepository {     /**      * Saves the given User with assigned data.      *      * @param ApplicationEntityUser $user      * @param array $data      * @return ApplicationEntityUser      */     public function saveUser(User $user, array $data = array())     {         $user­>setName($data['name']);         $user­>setEmail($data['email']);         $user­>setPassword($data['password']);         $this­>getEntityManager()­>persist($user);         return $user;     } }
  29. 29. Guilherme Blanco Service Layer no PHP 5.3 namespace ApplicationService ; use CoreServiceAbstractService ,     ApplicationEntityUser ; class UserService  extends AbstractService {     /**      * Creates a new User.      *      * @param array $data User data      */     public function createUser (array $data)      {         $validatorService  = $this­>locator­>getService('validator');         try  {              $data = $validatorService ­>validateUser ($data);              $user = new User();              $emWrite = $this­>getEntityManager ($this­>options['rw']);              return $emWrite­>transactional (function () use ($emWrite) {                  $userRepository  = $emWrite­>getRepository ('Application EntityUser');                  $user = $userRepository ­>saveUser($user, $data);                  return $user;              });         } catch (ApplicationExceptionValidatorException  $e) {              $loggerService  = $this­>locator­>getService('logger');              $loggerService ­>notify($e);         }         return null;     } }
  30. 30. Guilherme Blanco Service Layer no PHP 5.3 [default] ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Service Locator Configuration ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ resources.serviceLocator.context.adapterClass = "CoreServiceContextIniFileContext" resources.serviceLocator.context.options.path = APPLICATION_PATH "/configs/services.ini" resources.serviceLocator.context.options.serviceOptions.rw = read_write resources.serviceLocator.context.options.serviceOptions.r  = read
  31. 31. Guilherme Blanco Service Layer no PHP 5.3 [default] ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Doctrine Cache Configuration ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Points to default cache instance to be used. Optional is only one cache is defined resources.doctrine.cache.defaultCacheInstance = default ; Cache Instance configuration for "default" cache resources.doctrine.cache.instances.default.adapterClass = "DoctrineCommonCacheMemcacheCache" resources.doctrine.cache.instances.default.namespace    = "Application_" resources.doctrine.cache.instances.default.options.servers.0.host = localhost resources.doctrine.cache.instances.default.options.servers.0.port = 11211
  32. 32. Guilherme Blanco Service Layer no PHP 5.3 ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Doctrine DBAL Configuration ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Points to default connection to be used. Optional if only one connection is defined resources.doctrine.dbal.defaultConnection = read_write ; Database configuration resources.doctrine.dbal.connections.read_write.parameters.driver   = "pdo_mysql" resources.doctrine.dbal.connections.read_write.parameters.dbname   = "application" resources.doctrine.dbal.connections.read_write.parameters.host = "localhost" resources.doctrine.dbal.connections.read_write.parameters.port = 3306 resources.doctrine.dbal.connections.read_write.parameters.user = "app_rw_user" resources.doctrine.dbal.connections.read_write.parameters.password = "password" resources.doctrine.dbal.connections.read.parameters.driver   = "pdo_mysql" resources.doctrine.dbal.connections.read.parameters.dbname   = "application" resources.doctrine.dbal.connections.read.parameters.host = "localhost" resources.doctrine.dbal.connections.read.parameters.port = 3306 resources.doctrine.dbal.connections.read.parameters.user = "app_r_user" resources.doctrine.dbal.connections.read.parameters.password = "password"
  33. 33. Guilherme Blanco Service Layer no PHP 5.3 ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Doctrine ORM Configuration ; ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ; Points to default EntityManager to be used. Optional if only one EntityManager is defined resources.doctrine.orm.defaultEntityManager = read_write ; EntityManager configuration for "default" manager resources.doctrine.orm.entityManagers.read_write.connection     = read_write resources.doctrine.orm.entityManagers.read_write.proxy.namespace           = "ApplicationEntityProxy" resources.doctrine.orm.entityManagers.read_write.proxy.dir                 = APPLICATION_PATH "/../library/Application/Entity/Proxy" resources.doctrine.orm.entityManagers.read_write.metadataDrivers.0.adapterClass          = "DoctrineORMMappingDriverAnnotationDriver" resources.doctrine.orm.entityManagers.read_write.metadataDrivers.0.mappingNamespace      = "ApplicationEntity" resources.doctrine.orm.entityManagers.read_write.metadataDrivers.0.mappingDirs[]         = APPLICATION_PATH "/../library/Application/Entity" resources.doctrine.orm.entityManagers.read_write.metadataDrivers.0.annotationReaderClass = "DoctrineCommonAnnotationsAnnotationReader" resources.doctrine.orm.entityManagers.read_write.metadataDrivers.0.annotationReaderCache = default resources.doctrine.orm.entityManagers.read.connection           = read resources.doctrine.orm.entityManagers.read.proxy.namespace                = "ApplicationEntityProxy" resources.doctrine.orm.entityManagers.read.proxy.dir                      = APPLICATION_PATH "/../library/Application/Entity/Proxy" resources.doctrine.orm.entityManagers.read.metadataDrivers.0.adapterClass          = "DoctrineORMMappingDriverAnnotationDriver" resources.doctrine.orm.entityManagers.read.metadataDrivers.0.mappingNamespace      = "ApplicationEntity" resources.doctrine.orm.entityManagers.read.metadataDrivers.0.mappingDirs[]         = APPLICATION_PATH "/../library/Application/Entity" resources.doctrine.orm.entityManagers.read.metadataDrivers.0.annotationReaderClass = "DoctrineCommonAnnotationsAnnotationReader" resources.doctrine.orm.entityManagers.read.metadataDrivers.0.annotationReaderCache = default
  34. 34. Guilherme Blanco Service Layer no PHP 5.3 [logger] class = "ApplicationServiceLoggerService" [validator] class = "ApplicationServiceValidatorService" [user] class = "ApplicationServiceUserService"
  35. 35. Guilherme Blanco Service Layer no PHP 5.3 use ApplicationControllerAction; /**  * UserController class.  *  * @author Guilherme Blanco <guilhermeblanco@hotmail.com>  */ class UserController extends Action {     /**      * Create a new user.      *      * /user/create      */     public function createAction()      {         $userService = $this­>getServiceLocator()­>getService('user');         $user = $userService­>createUser($this­>getRequest()­>getParams());         $this­>view­>user = $user;     } }
  36. 36. Guilherme Blanco Service Layer no PHP 5.3 Perguntas?

×