Alternative paradigms to MVC?

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Alternative paradigms to MVC?

Post by Jenk »

On the query side, you don't worry about events. You do the simplest, quickest thing to get the "answer". If that means literally writing a query to return a result set, and decorating it with a view then so be it (perhaps something like "getHomePageForUserId($userId)". :)

Domain model will only be used on the command side.

You are right in that Event Sourcing and CQRS are unrelated, but they fit together really, really well. So if not using CQRS, then either return the event or register on the event an action to display the results (the latter for Command pattern completeness).
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Alternative paradigms to MVC?

Post by josh »

1 - Can you explain why you think people say "use exceptions for only exceptional behavior" and your views tend to differ?
2 - What does the code look like, just a try block, with the catch blocking ending execution, and the 'finally' block logging the command (that way it only logs succeeded commands?)
3 - what about keeping track of reads. Later I might want to do a query that asks for users that looked at a given page. If my reads don't even cause events, how is event sourcing providing the benefits it promises?
4 - if a command is defined as something that modifies state, how do my 'reads' record some state (I guess there is no strict definition for a read, or by logging it it becomes re-purposed as a command rather than a read?). In this case I need the foresight to log it, which means there is little benefit over a traditional log?
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Alternative paradigms to MVC?

Post by Jenk »

My views don't differ at all. In fact they are further enforced when using CQRS. If a Command is issued, and that command cannot complete - that is an exception.

Code: Select all

try {
  $someObject->doSomething();
} catch (CouldNotDoSomethingException $e) {
  // etc.
}
I tell an object to do something (give it a command), I expect it to do it. If it cannot complete the command, that is a deviation from the expected path/flow, and thus an exception.

That's if it's a CQRS implementation.. but as the latter part of my post points out, if it is not then returning (not throwing) the event is fine.

Code: Select all

$someEvent = $someObject->doSomethingAndReturnTheEvent();
$eventStore->Store($someEvent);
Trigger an event/command to record the action of the user link click (and the validate security etc) - but when fetching the result, do it in the quickest way. The command is to increase the counter (or whatever) but the read operation is still a separate operation.

Code: Select all

$command = new UserClickedOnFooLink($user);
$commandHandler->Handle($command);
echo $queryHandler->GetViewForFooLinkForUser($user);
Anyway, this is more about CQRS than it is Event Sourcing. Event Sourcing is simply using an Event Store to persist your domain state as a sequence of changes, instead of a set of values that you update (i.e. 'current state').

Here is another link by Greg Young (the guy in the video I posted earlier) titled "Why use Event Sourcing?" http://codebetter.com/blogs/gregyoung/a ... rcing.aspx which will (hopefully) make things clearer.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Alternative paradigms to MVC?

Post by Jenk »

Another link to try.. here is an example C#.NET project (ASP.NET MVC2) showing the full thing, if you fancy a peruse: http://github.com/gregoryyoung/m-r
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Alternative paradigms to MVC?

Post by josh »

Jenk wrote: The command is to increase the counter (or whatever) but the read operation is still a separate operation.

Code: Select all

$command = new UserClickedOnFooLink($user);
$commandHandler->Handle($command);
echo $queryHandler->GetViewForFooLinkForUser($user);
Thanks that makes it incredibly more clear. Now back to the example of a login, if doing CQRS & event sourcing, would you put the login check on the 'read' side or the 'command' side or both? Would the command side method 'ask' for data from the read side by declaring a parameter? Could you describe or show the method signatures for something like a login, with both read side & command side implementation so I can see how they work together?

Something like this: ?

Code: Select all

// domain logic
function handleCommand( $I_need_some_data_from_the_read_store_to_work ) {
 // do stuff with data injected from the read store
}
Or, I guess typically the data would be state on the domain model that is sourced from events (duh), but with something like a login, a user should not have everyone's password for it's state (duh). So I'm still left with some cognitive dissonance on how CQRS & event sourcing co-exist.

Maybe something like a parameter on the command $succeeded, the flag would be set before the command is passed to the domain model? If so what would that look like? Or maybe you'd have a 'login manager' and you'd play back the 'signup events', and this object would decide if a password is valid or not?
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Re: Alternative paradigms to MVC?

Post by Jenk »

There will be some areas of cross-over. When we asked Greg about this (myself and some colleagues were at the talk in the video I posted) over some geek beers about these areas, he said in his experience the simplest was to just go with a comparison from the read model, before firing the event. e.g.:

Code: Select all

public function UserTriedToLogin($username, $password) {
  if ($queryModel->userWithCredentialsExists($username, $password)) {
    $commandModel->handle(new UserLoggedInCommand($user));
  } else {
    // throw exception, or regenerate view etc.
  }
}
Post Reply