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.

of

Application Layer in PHP Slide 1 Application Layer in PHP Slide 2 Application Layer in PHP Slide 3 Application Layer in PHP Slide 4 Application Layer in PHP Slide 5 Application Layer in PHP Slide 6 Application Layer in PHP Slide 7 Application Layer in PHP Slide 8 Application Layer in PHP Slide 9 Application Layer in PHP Slide 10 Application Layer in PHP Slide 11 Application Layer in PHP Slide 12 Application Layer in PHP Slide 13 Application Layer in PHP Slide 14 Application Layer in PHP Slide 15 Application Layer in PHP Slide 16 Application Layer in PHP Slide 17 Application Layer in PHP Slide 18 Application Layer in PHP Slide 19 Application Layer in PHP Slide 20 Application Layer in PHP Slide 21 Application Layer in PHP Slide 22 Application Layer in PHP Slide 23 Application Layer in PHP Slide 24 Application Layer in PHP Slide 25 Application Layer in PHP Slide 26 Application Layer in PHP Slide 27 Application Layer in PHP Slide 28 Application Layer in PHP Slide 29 Application Layer in PHP Slide 30 Application Layer in PHP Slide 31 Application Layer in PHP Slide 32
Upcoming SlideShare
CQRS
Next
Download to read offline and view in fullscreen.

1 Like

Share

Download to read offline

Application Layer in PHP

Download to read offline

Vortrag über eine beispielhafte Implementierung eines Application Layers in PHP

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Application Layer in PHP

  1. 1. Application Layer ein Vortrag von Per Bernhardt
  2. 2. Agenda • Disclaimer / Credits • Ein kleines bisschen Theorie • Ein echtes Beispiel: Chefkoch API
  3. 3. Credit goes to… • http://martinfowler.com/ • http://domainlanguage.com/ • http://alistair.cockburn.us/ • http://www.whitewashing.de/ • und viele andere..
  4. 4. Ein bisschen Theorie…
  5. 5. Application Layer Presentation Layer Infrastructure Layer Domain Layer
  6. 6. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP
  7. 7. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP - Fasade - Transaktionen - Sicherheit / Zugriffsschutz - Integration / Orchestrierung
  8. 8. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP - Fasade - Transaktionen - Sicherheit / Zugriffsschutz - Integration / Orchestrierung - Daten - Geschäftslogik
  9. 9. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP - Fasade - Transaktionen - Sicherheit / Zugriffsschutz - Integration / Orchestrierung - Daten - Geschäftslogik - Datenbank - Mailserver - Logger - …
  10. 10. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP - Fasade - Transaktionen - Sicherheit / Zugriffsschutz - Integration / Orchestrierung - Daten - Geschäftslogik - Datenbank - Mailserver - Logger - …
  11. 11. Application Layer Presentation Layer Infrastructure Layer Domain Layer - Controller - Template / HTML - Session / HTTP - Fasade - Transaktionen - Sicherheit / Zugriffsschutz - Integration / Orchestrierung - Daten - Geschäftslogik - Datenbank - Mailserver - Logger - …
  12. 12. Chefkoch API
  13. 13. POST /cookbooks/{id}/categories
  14. 14. <?php ! namespace ChefkochBundleApiBundleController; ! use SymfonyBundleFrameworkBundleControllerController; use ChefkochDomainModelCookbookCookbookId use SensioBundleFrameworkExtraBundleConfigurationParamConverter; use ChefkochBundleApiBundleAnnotationApiSerialize; use ChefkochApplicationCookbookRequest; use ChefkochApplicationCookbookCommand; use PixelhouseApplicationEventDispatchingService; use PixelhouseApplicationResponse; ! class CookbookController extends Controller { ! ... ! /** * @ParamConverter("category", options={"deserialize"=true}) * @ApiSerialize * @return Response */ public function saveCategoryAction(CookbookId $cookbookId, RequestCategoryRequest $category) { return $this->getCookbookService()->execute( new CommandSaveCategoryCommand($cookbookId, $category) ); } ! ... ! /** * @return DispatchingService */ private function getCookbookService() { return $this->get('chefkoch_api.application.cookbook_service'); } }
  15. 15. <?php ! namespace ChefkochApplicationCookbookCommand; ! use ChefkochApplicationCookbookRequestCategoryRequest; use ChefkochApplicationCookbookSecurityCookbookWriteAccessRequired; use ChefkochDomainModelCookbookCookbookId; use PixelhouseApplicationCommand; ! class SaveCategoryCommand implements Command, CookbookWriteAccessRequired { ! /** @var CookbookId */ private $cookbookId; ! /** @var CategoryRequest */ private $categoryRequest; ! public function __construct(CookbookId $cookbookId, CategoryRequest $categoryRequest) { $this->cookbookId = $cookbookId; $this->categoryRequest = $categoryRequest; } ! public function getCookbookId() { return $this->cookbookId; } ! public function getCategoryRequest() { return $this->categoryRequest; } }
  16. 16. <?php ! namespace PixelhouseApplicationEvent; ! use PixelhouseApplicationCommand; use PixelhouseApplicationUseCase; use PixelhouseEventDispatcherEventDispatcher; ! class DispatchingService { ! /** @var EventDispatcher */ private $eventDispatcher; ! /** @var UseCase[] */ private $useCases = array(); ! public function __construct(EventDispatcher $eventDispatcher) { $this->eventDispatcher = $eventDispatcher; } ! public function registerCommand($commandClass, UseCase $useCase) { $this->useCases[$commandClass] = $useCase; } ! public function execute(Command $command) { ... } }
  17. 17. <?php ! namespace PixelhouseApplicationEvent; ! class Events { const PRE_COMMAND = 'application.pre_command'; const POST_COMMAND = 'application.post_command'; const EXCEPTION = 'application.exception'; }
  18. 18. <?php ! namespace PixelhouseApplicationEvent; ! use PixelhouseApplicationCommand; ! class DispatchingService { ! ... ! public function execute(Command $command) { try { $this->eventDispatcher->dispatch( Events::PRE_COMMAND, new CommandEvent($command) ); $response = $this->useCases[get_class($command)]->run($command); $this->eventDispatcher->dispatch( Events::POST_COMMAND, new PostCommandEvent($command, $response) ); ! return $response; } catch (Exception $exception) { $event = new CommandExceptionEvent($command, $exception); $this->eventDispatcher->dispatch( Events::EXCEPTION, $event ); if ($response = $event->getResponse()) { return $response; } else { throw $exception; } } } }
  19. 19. <?php ! namespace ChefkochInfrastructureApplication; ! use PixelhouseApplicationEvent; use PixelhouseEventDispatcherSubscriber; use DoctrineORMEntityManager; ! class DoctrineTransactionListener implements Subscriber { ! /** @var EntityManager */ private $entityManager; ! public function __construct(EntityManager $entityManager) { $this->entityManager = $entityManager; } ! public function preCommand(EventCommandEvent $event) { $this->entityManager->getConnection()->beginTransaction(); } ! public function postCommand(EventPostCommandEvent $event) { $this->entityManager->flush(); $this->entityManager->getConnection()->commit(); } ! public function onException(EventCommandExceptionEvent $event) { $this->entityManager->close(); if ($this->entityManager->getConnection()->isTransactionActive()) { $this->entityManager->getConnection()->rollBack(); } } }
  20. 20. <?php ! namespace PixelhouseApplicationSecurity; ! use PixelhouseApplicationEvent; use PixelhouseEventDispatcherSubscriber; ! class SecurityListener implements Subscriber { ! /** @var Context */ private $context; ! /** @var Policy[] */ private $policies = array(); ! public function __construct(Context $context) { $this->context = $context; } ! public function addPolicy(Policy $policy) { $this->policies[] = $policy; } ! /** * throws Exception */ public function preCommand(EventCommandEvent $event) { foreach ($this->policies as $policy) { $policy->check($this->securityContext, $event->getCommand()); } } }
  21. 21. <?php ! namespace ChefkochApplicationCookbookSecurity; ! use ChefkochDomainModelCookbookCookbookRepository; use ChefkochUserDomainModelUserRepository; use PixelhouseApplicationCommand; use PixelhouseApplicationSecurityAccessDeniedException; use PixelhouseApplicationSecurityContext; use PixelhouseApplicationSecurityPolicy; ! class CookbookAccessPolicy implements Policy { ! /** @var CookbookRepository */ private $cookbookRepository; ! /** @var UserRepository */ private $userRepository; ! public function __construct(CookbookRepository $cbRepo, UserRepository $uRepo) { $this->cookbookRepository = $cbRepo; $this->userRepository = $uRepo; } ! public function check(Context $context, Command $command) { if ($command instanceof CookbookWriteAccessRequired) { $cookbook = $this->cookbookRepository->findOneById($command->getCookbookId()); $user = $this->userRepository->findOneById($context->getUserId()); ! // Zugriff prüfen ... ! throw new AccessDeniedException(); } } }
  22. 22. <?xml version="1.0" ?> <container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services ..."> <services> ... ! <service id="chefkoch_api.application.use_case.cookbook_save_category" class="ChefkochApplicationCookbookUseCaseSaveCategory"> <argument type="service" id="chefkoch_api.infrastructure.cookbook_category_repository" /> <argument type="service" id="chefkoch_api.infrastructure.user_repository" /> <argument type="service" id="chefkoch_api.application.security_context" /> <tag name="chefkoch_api.application.use_case" commandClass="ChefkochApplicationCookbookCommandSaveCategoryCommand" applicationService="chefkoch_api.application.cookbook_service" /> </service> ! ... </services> </container>
  23. 23. <?php ! namespace ChefkochApplicationCookbookUseCase; ! use ChefkochApplicationCookbookCommandSaveCategoryCommand; use PixelhouseApplicationSecurityContext; use PixelhouseApplicationUseCase; use ChefkochDomainModelCookbookCategoryRepository; use ChefkochUserDomainModelUserRepository; ! class SaveCategory implements UseCase { ! /** @var CategoryRepository */ private $categoryRepository; ! /** @var UserRepository */ private $userRepository; ! /** @var Context */ private $context; ! public function __construct(CategoryRepository $cRepo, UserRepository $uRepo, Context $context) { $this->categoryRepository = $cRepo; $this->userRepository = $uRepo; $this->context = $context; } ! public function run(SaveCategoryCommand $command) { ... } }
  24. 24. <?php ! namespace ChefkochApplicationCookbookUseCase; ! use PixelhouseApplicationUseCase; use ChefkochApplicationCookbookCommandSaveCategoryCommand; use ChefkochDomainModelCookbookCategory; use ChefkochApplicationCookbookNotificationCategorySavedSuccess; use ChefkochApplicationCookbookResponseCategoryResponse; use PixelhouseApplicationResponse; ! class SaveCategory implements UseCase { ... ! public function run(SaveCategoryCommand $command) { $user = $this->userRepository->findOneById($this->context->getUserId()); ! $category = new Category( $command->getCookbookId(), $user->getId(), $command->getCategoryRequest()->getName(), $command->getCategoryRequest()->getDescriptionText() ); ! $this->categoryRepository->add($category); ! $categoryResponse = new CategoryResponse($category, $user); ! $response = new Response(); $response->getNotification()->addMessage(new CategorySavedSuccess($categoryResponse)); ! return $response; } }
  25. 25. HTTP/1.1 201 Created
  26. 26. Per Bernhardt info@perprogramming.de perprogramming.de slideshare.net/perprogramming
  27. 27. Bilder • Warning: https://www.flickr.com/photos/gerardstolk/ 6538330609 • Show Time: https://www.flickr.com/photos/ florida_photo_guy/5212663826 • Question Marks: https://www.flickr.com/photos/ loneblackrider/315302588 • Thank You: https://www.flickr.com/photos/wwworks/ 4759535950
  • bezrukovp

    Aug. 22, 2016

Vortrag über eine beispielhafte Implementierung eines Application Layers in PHP

Views

Total views

3,214

On Slideshare

0

From embeds

0

Number of embeds

4

Actions

Downloads

14

Shares

0

Comments

0

Likes

1

×