Slide 1

Slide 1 text

TASK BASED UIS

Slide 2

Slide 2 text

STIJN VANNIEUWENHUYSE @STIJNVNH

Slide 3

Slide 3 text

THIS TALK IS NOT ABOUT UI DESIGN

Slide 4

Slide 4 text

THIS TALK IS ABOUT SOFTWARE DESIGN

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

CRUD CREATE READ UPDATE DELETE

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

$ git push origin master To https://github.com/stivni/doodis.git ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'https://github.com/stivni/doodis.git' To prevent you from losing history, non-fast-forward updates were rejected Merge the remote changes (e.g. 'git pull') before pushing again. See the 'Note about fast-forwards' section of 'git push --help' for details.

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

No content

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

SOFTWARE SHOULD GUIDE ITS USERS THROUGH THE BUSINESS PROCESS

Slide 18

Slide 18 text

SOFTWARE SHOULD DELIVER VALUE TO THE BUSINESS

Slide 19

Slide 19 text

HOW?

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

No content

Slide 23

Slide 23 text

$customer->moveTo( new Address( $street, $number, $zip, $city, $country ) ); $order->pay(Money::EUR(100)); $order->checkout();

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

COMMAND PATTERN

Slide 27

Slide 27 text

File a bug Acknowledge a bug Decline a bug Describe a bug Categorize a bug Close a bug

Slide 28

Slide 28 text

FileBug AcknowledgeBug DeclineBug DescribeBug CategorizeBug CloseBug

Slide 29

Slide 29 text

class FileBug implements Command { private $id; private $description; public function __construct($id, $description) { //… } public function getId() { return $this->id; } public function getDescription() { return $this->description; } }

Slide 30

Slide 30 text

class FileBugCommandHandler implements CommandHandler { private $bugRepository; public function __construct(BugRepository $bugRepository) { //… } public function handle(FileBug $command) { $this->bugRepository->add( new Bug( $command->getId(), $command->getDescription() ; } }

Slide 31

Slide 31 text

class SimpleCommandDispatcher implements CommandDispatcher { /** @var CommandHandler[] */ private $commandHandlers; public function dispatch(Command $command) { $commandType = $this->getTypeFromCommand($command); $this->commandHandlers[$commandType]->handle($command); } public function registerHandler(CommandHandler $commandHandler) { $commandType = $this->getTypeFromCommandHandler($command); $this->commandHandlers[$commandClass] = $commandHandler; } //private function getTypeFromCommand(Command $command) //private function getTypeFromCommandHandler(CommandHandler $command) }

Slide 32

Slide 32 text

{ “commandName”: “\\NameSpaced\\FileBug”, “payload”: { “id”: “1”, “description”: “The software doesn’t work” } }

Slide 33

Slide 33 text

class SimpleJsonCommandDeserializer implements CommandDeserializer { public function deserialize($data) { $reflectionClass = new ReflectionClass($data->commandName); return $reflectionClass->newInstanceArgs($data->payload); } }

Slide 34

Slide 34 text

class CommandDispatcherController { // /api/command/dispatch public function deserialize($serializedCommand) { $command = $this->commandDeserializer->deserialize( $serializedCommand ); $commandDispatcher->dispatch($command); return new Response(“OK”, 200); } }

Slide 35

Slide 35 text

DOODIS SOON ON MY GITHUB

Slide 36

Slide 36 text

BUT HOW DOES THIS AFFECT THE UI?

Slide 37

Slide 37 text

No content

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

SEPARATE READ MODELS

Slide 42

Slide 42 text

[ { “bugId”: “1”, “description”: “Checkout fails with order >= 100 EUR” “affectedFeature”: “CheckoutOrder”, “usageOfFeature”: “2233” }, … ]

Slide 43

Slide 43 text

class BugStatistic implements JsonSerializable { private $bugId; private $description; private $affectedFeature; private $usageOfFeature; //public function __constructor(…) //public function jsonSerialize() }

Slide 44

Slide 44 text

class BugStatisticsController { /** @var BugStatisticsRepository */ private $bugStatisticsRepository; // /api/bugs/statistics/overview public function overview() { $statistics = $this->bugStatisticsRepository->findAll(); return new Response(json_encode($statistics)); } }

Slide 45

Slide 45 text

class QueryingBugStatisticsRepository implements BugStatisticsRepository { public function findAll() { $sql = ‘SELECT * FROM bugs JOIN usage ON bug.feature = usage.feature’; return array_map( function($record) { return new BugStatistic( $record->id, $record->description, $record->feature, $record->usage ); }, $this->fetchAll($sql) ); } }

Slide 46

Slide 46 text

CQRS COMMAND QUERY RESPONSIBILITY SEGREGATION PRINCIPLE

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

MY APPLICATION IS JUST CRUD

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

PROCESSES ARE HARDCODED I WANT MORE FLEXIBILITY

Slide 55

Slide 55 text

BUILDING GOOD SOFTWARE IS ABOUT MAKING THE RIGHT TRADEOFFS

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

QUESTIONS?

Slide 58

Slide 58 text

THANK YOU I’M STIJN VANNIEUWENHUYSE @STIJNVNH PLEASE LEAVE FEEDBACK JOIND.IN/13112