Wednesday, May 16, 2012

CQRS Pattern

Command Query Responsibility Segregation


This topic looks like BIG ENTERPRISE pattern for BIG and distributed systems.
But on the other hand it comes with nice idea that Command and Query are different and that gives a lot of flexibility in system design for the price of increased complexity, as usual.

So you take regular sync operation (pictures are from Martin Fowler and Udi Dahan blogs):


And you say that "Command Model" (usually more complex) and "Query Model" (usually basic select * from few joins ) could have different implementations:



And then you continue: "Query Model" becomes "Cache" and "Command Model" becomes "Event Sourcing" storage.



And you continue even more:
- start to treat UI as a "Task based UI flow"
- and "Commands" are stored in the DB (pretty much write-only DB) so you have "free" History
- and you may play "Commands" back and force and you practically don't need transaction logs.
- and you have many "Caches" designed for specific UI layouts
- and so on...

So "current" state of the Model is kind of blurry now and may require Rules Engine or some implementation of "Snap shoot" (this can be done during Command execution).

Martin Fowler gives good definition for pattern: http://martinfowler.com/bliki/CQRS.html
Udi Dahan talks about details: http://www.udidahan.com/2009/12/09/clarified-cqrs/
Some links and discussion/video from Chicago ALT.NET: http://chicagoalt.net/event/January2010Meeting-JdnpresentsCQRSinroughlyanhourorso



Monday, May 7, 2012

Tuesday, May 1, 2012

DCI #2



A week ago I spotted very inspiring video: http://vimeo.com/34522837 "Some Thoughts on Classes After 18 Months of Clojure" from Brian Marick [BM] and found  mentions about DCI in the comments.

Brian Marick treats objects as a set of features (traits) which could be used as Roles in UseCase (DCI context) implementation.

In real life even simplest object has millions of properties and features but every time I need only few and at this time I don't care about other features. I can touch and feel (getters) this object and use it (setters and methods). Kind of interface with real implementation and real properties.
Next time I may touch/use same object in different context, the interface may be the same or new, but properties with same name are indeed same properties as I am using exactly same object. Methods should be different (or same? same is easier in case of JavaSctipt), that's I am not sure yet.
So object becomes a container of all such sets of features (traits).

Technically it is pretty easy to implement:
1) define HUGE class and many interfaces with getters/setters and functions. This way is not interesting.
2) Use dynamic features of language and treat each instance as a Hash of properties and methods. Pretty easy in JavaScript.
In C# it may look like this http://houseofbilz.com/archives/2010/05/08/adventures-in-mvvm-my-viewmodel-base/

// Trait here is ViewModelBase from above article: class with Hash and few helper methods Get(), Set(), With(), As()

public class Account: Trait
{
// strongly types property
public double Balance
{
   get { return Get(() => Balance, 0.0 /* This is the default value */); }
   set { Set(() => Balance, value);}
}

public void Withdraw(double amount) { Balance -= amount; }

public void Deposit(double amount) { Balance += amount; }
}

public class BalanceChangesTrace: Trait
{
// this Balance is mapped to Account via Hash
private double Balance
{
get { return Get(() => Balance); } // it will take value from Hash
}

[DependsUpon("Balance")]
public void LogWhenBalanceChanges()
{
Console.WriteLine("New Balance is {0}", Balance);
}
}

public class OverdraftProtection: Trait
{
// I may repeat private double Balance { get { return Get(() => Balance); } }
// but there is another way to get Balance

[DependsUpon("Balance")]  // this method will be called each time Account.Balance is set.
public void LogWhenBalanceChanges()
{
var balance = this.As().Balance;

if ( balance < 0 ) throw new ApplicationException("insufficient funds");

// or even untyped, bad practice in general but may be handy sometimes
// double balance = (double)this.Get("Balance")
}
}

public class AccountTransferUseCase: Context
{
    public void Transfer(Account from, Account to, double amount)
    {
    var _from = from
.With()
    .With();

    var _to = to
 .With();

Console.WriteLine("Withdrawing " + amount);
        _from.Withdraw(amount);
       
        Console.WriteLine("Depositing " + amount);
        _to.Deposit(amount);
    }
}

var acc1 = new Account();
acc1.Balance = 100.0;

var acc2 = new Account();

(new AccountTransferUseCase()).Transfer(from: acc1, to: acc2: amount: 20.0);


With all these dynamics it may be slow but for most software it is fast enough.


[end]