Friday, March 25, 2011

vaccine framework example - preview 3 (create order)

Salam

Adad beberapa minor changes dlm codebase vaccine framework, yang utama sekali ialah macam maner aku nak handle part read side iaitu reporting.Aku akan sentuh part nie nanti. Tetapi untuk sekarang nie aku nak tunjukkan bagaimana aku pecahkan relation Customer dari Order dan pecahkan relation OrderLine dari Product.

Kalau tengok balik domain diagram yang sebelum nie, domain diagram ini adalah cara design yang kebiasaan dari kita akan buat apabila menggunakan cara n-tier, dimana dlm domain tersebut kita ubah, dalam domain tersebut juga kita baca latest state object tersebut untuk kita tunjukkan kepada client balik dan kebiasaan juga, process ini akan melibatkan kita map dengan class Data Transfer Object untuk reshape maklumat kepada UI screen di client.



Selepas tu aku cakap jika menggunakan DCI+CQSR+Event Sourcing, kita boleh pecahkan relation tadi dan letakkan reference tersebut berada dalam Role, dan relation ini bersifat sementara.Kenapa Role penting? Ini adalah kerana kita boleh share role diantara aggregateroot object yang lain dengan syarat aggregateroot object tersebut juga perlulah memenuhi contract Role yang didefine. Dan di dalam Role jugalah berlaku interaction antara object, sebagai contoh jika condition ini berlaku, execute object yang itu, etc.

Berbalik pada demo code yang aku nak tunjuk, sebelum nie aku dah tunjukkan bagaimana nak create Customer, tetapi ada beberapa code penting aku terlupa nak cerita, menyebabkan terdapat beberapa kekeliruan.InsyAllah aku cuba terangkan dengan lebih lengkap dalam n3 kali ini.

Untuk create Order bagi specific Customer, kita perlu lah juga ada Product, so process untuk create Product adalah lebih kurang macam mana nak create Customer.

Jadi sekarang nie aku dah adalah list Customer dan aku juga dah ada list Product. UI dia ada seperti ini:



Langkah seterunya ialah aku define object Order, dan class code dia adalah seperti ini. Code dalam class Order sebenarnya dibina secara incremental tapi payah nak tunjuk satu-satu, so aku show complete class Order.



Line 5 , menunjukkan Order mengandungi OrderLine dan object OrderLine nie ialah child object bagi Order. Line 52, ialah complete OrderLine, dan lihatlah berapa simple class tersebut.

Line 11 dan 12 pula, kita perlu registerkan event handler yang akan execute apabila kita replay balik semula event2 tersebut.Ok buat masa nie, kita tingglkan sekejap class Order nie.

Next, aku perlu define pula apa Command yang perlu dibuat untuk melakukan Order bagi Customer. So disini aku define Command - MakeNewOrderCommand



Code yang ini pun cukup straight forward, cuma aku define dictionar collection ialah bagi aku combinekan selection product dan juga berapa quantity.

Seterusnya ialah dengan define Role, apa Role yang akan memainkan peranan dalam melakukan Order dan siapa AggregateRoot yang akan menjadi RolePlayer?

Aku memilih Order object sebagai AggregateRoot dan juga menjadi RolePlayer untuk Role MakeNewOrderRole.



Ok jom kena tengok apa yang menarik didalam Role ini. Line 5, aku perlu mapkan apa command yang akan digunakan dalam Role ini.
Beri perhatian pada Line 7.Pada Line 7 ini, aku akan load AggregateRoot Customer hanya dengan Id, apa yang berlaku dibelakang scene ialah, vaccine framework akan baca setiap event dalam eventsnapshot source untuk aggregateroot customer dan akan replay event-event tersebut.



Okay lihat semula pada code Customer, sebelum ini kita dah registerkan Customer tersebut untuk terima 2 jenis event iaitu event NewCustomerCreatedEvent dan CashBalanceDecreasedEvent. Line 25, OnNewCustomerCreated ini lah vaccine framework akan trigger semula apabila direplay jika ada event NewCustomerCreatedEvent, dari situ kita dapat lihat bagaimana sesuatu AggregateRoot object dibina state2 object tersebut.

Ambil masa dan kaji macam maner interaction between object berlaku didalam Role dan bagaimana juga Role ini nanti boleh dishare dengan AggregateRoot object yang lain sebagai RolePalyer. Kalau sekarang nie RolePlayer ialah Order, ada kemungkinan process Order ini tetapi aku nak menggunkan keatas AggregateRoot object yang lain seperti Sale etc? Cuma sekarang nie mengambil konsep "YAGNI", kita hanya concentrate pada objective yang hendak dicapai, jika ada keperluan untuk dishare pada masa tu kita akan buat minor refactor.

Line 14 kita akan replay event untuk Product pula, process sama macam yang diterangkan, manakala Line 22,23,24 ketiga3 AggregateRoot akan memainkan peranan untuk execute method2 bagi menjayakan hasrat Role itu tadi.

Okay Line 23, customer.DecreaseCashBalance(totalAmount), singkap balik code dalam Customer dimana method DecreaseCashBalance dan lihat apa yang berlaku.


public void DecreaseCashBalance(decimal totalAmount)
{
if (cashBalance >= totalAmount)
{
cashBalance -= totalAmount;
var e = new CashBalanceDecreasedEvent { CashBalance = cashBalance };
Apply(e)
.UpdateReport(r => r.cashBalance = cashBalance);
}
else
{
throw new Exception("Insufficent amount to deduct");
}
}



Okay yang ini pula ialah code di client


private ActionResult MakeAnOrderComplete(CustomerOrderViewModel model)
{
try
{
var cmd = new MakeNewOrderCommand { CustomerId = new Guid(Request.Params["CustomerId"]) };
foreach (var item in model.OrderItems)
{
cmd.Quantities.Add(item.ProductId, item.Quantity);
}

using (var s = UnitOfWork)
{
var ctx = new ContextHandler(repo);
ctx.Bind(cmd)
.Execute();
s.Commit();
}

return MakeAnOrder();
}
catch(Exception err)
{
throw err;
}
}



Ada beberapa, part yang aku belum sentuh, insyAllah dalam n3 yang lain, n3 nie pun dah agak panjang.

https://github.com/ryzam/VaccineWeb-Preview - Code

Wednesday, March 23, 2011

vaccine framework example - preview 2 (create customer)

Salam kepada Datuk T :) sempena hari porno se1Malaysia

Ok untuk meneruskan kerja jahat, opps kerja baik dari entry part 1 , saya akan tunjukkan contoh dan bukti bagaimana hendak menggunakan vaccine framework dimana anda akan start dengan pengalaman baru cara DCI + CQRS + ES(Event Sourcing) di combinekan.


Demo nie dalam ASP.Net MVC3. Aku create simple web solution dan didalam folder Models aku perlu create 6 folder iaiatu:

1. Commands
2. Domains
3. EventHandlers
4. Events
5. Reports
6. RoleHandlers

Imej seperti dibawah ini.





1. Create Customer class object
Aku akan tulis first code iaitu customer class didalam folder Domains/Customers



Perhatikan ada beberapa perkara penting aku perlu letak didalam class Customer. Pertama aku perlu extends AggregateRoot, ini adalah penting untuk framework execute function replay apabila load object dari storage. So convention ini juga menunjukkan Customer adalah AggregateRoot dan aku juga perlu implement IRolePlayer untuk membolehkan Customer untuk host apa-apa role yang diberi semasa runtime execution selagi mengikut role contract, very flexible dan dynamic.

2. Create command
Berikutnya, aku perlu tulis command class untuk digunakan sebagai message dari client ke server seperti ini. Tiada yang istimewa cuma perlu di extends ke command. Command akan digunakan di client sebagai mapping user mental model yang mengandungi maklumat dan operation yang hendak dilakukan.



3. Create Role
Selepas aku dah create domain(aggregateroot) dan juga command, seterusnya aku kena define Role. Role antara element yang penting/core dlm vaccine framework, dimana Role ini boleh sahaja dishare antara domain object yang lain dengan syarat domain object yang lain memenuhi contract RoleMethod. Contoh Role dalam demo app nie seperti berikut ini.



Self ialah keyword yang akan map balik kepada AggregateRoot so dalam kes ini Self ialah Customer.Self akan ada method CreateNewCustomer(c.Name,c.CashBalance), then perhatikan balik dalam code Customer diatas, dimana dalam method tersebut, kita hanya akan hasilkan event apabila method tersebut berlaku. Event tersebut akan diletakkan dalam method Apply iaitu salah satu method dalm vaccine framework berfungsi untuk store event kedalam event source dan eventsnapshot source, selain dari itu reporting component juga berada dalam Apply method. Event yang dihasilkan dalam process CreateNewCustomer ialah NewCustomerCreatedEvent. Code NewCustomerCreatedEvent adalah seperti ini.



4. Masukkan reporting


Seterusnya, apabila event tadi terhasil, selain dari disimpan kedalam event source dan juga eventsnapshot source, bahagian report juga untuk read process akan juga berlaku. Aku perlu create bagaimana report yang aku ingin keluarkan, report boleh digunakan untuk view di screen. So aku tidak perlu lagi ada join table, sebalinya setiap view UI akan ada report masing-masing.



EventHandler yang mengawal samaada update atau create new report ialah seperti ini



Aku akan tunjuk, rupa eventsnapshot source dan customerreport datasource.

EventSnapshotSource


CustomerDetailReport



Ringkasan

Ini adalah preview simple bagaimana menggunakan vaccine framework. InsyAllah akan buat demo dengan scenario yang lagi complex selepas ini.

Tuesday, March 22, 2011

vaccine framework example - preview 1

Salam

Ok, just nak tunjuk simple example macam maner vaccine framework berfungsi. So example yang paling mudah ialah classic example customer order product. Rules yang perlu ada ialah order mestilah tak lebih dari balance amount yang ada pada customer dan juga quantiti order product mestilah kurang atau sama dari available quantiti stock pada setiap product yang dipilih.

So, langkah pertama macam maner kita nak design domain model dia? Kalau normal domain model design kita akan hasilkan design seperti ini



Domain diatas digunakan untuk write dan read, so akan ada join table sana dan sini untuk hasilkan maklumat tertentu ke screen atau apa-apa bentuk reporting.

Domain design menggunakan vaccine framework pula akan hasilkan design sebegini



Hasilnya tiada lagi reference order ke customer dan tiada lagi reference orderline ke product. So mana perginya reference ini. Kalau dilihat dalam image reference tu sekarang berada dalam makeorderrole tetapi ianya hanyalah short term reference, hanya berlaku apabila role tersebut digunakan. Maklumat reference disimpan didalam event untuk read model.

Oleh kerana ini adalah preview untuk vaccine framework, so untuk detail pasal architecture akan dibincang di lain kali.

Antara konsep yang penting dalam cqrs ialah messaging. Message terbahagi kepada 2 bahagian, command dan juga event.

Command dimap kepada verb dan dalam bentuk "present tense" seperti RegisterNewCourse etc.

Manakala event pula ialah sesuatu yang telah berlaku hasil dari process dari command. Name convention untk map ialah seperti berikut NewCourseRegistered ianya juga map kan verb dalam bentuk "past tense".

Okay cukup serba sedikit pasal command dan event, berbalik semula kepada macam maner hendak hasilkan solution kepada user story yang kat atas berserta rules yang perlu dipenuhi.

Apabila menggunakan vaccine framework, ada 3 object penting perlu di kenal pasti sebelum pergi ke step seterusnya. Pertama sekali kena kenal pasti

1. RolePlayer - Object yang akan menggunakan Role didalam berkomunikasi dengan object2 yang lain.

2. Command Message - Ialah intention/mental model dari user kepada system untuk buat sesuatu.

3. RoleMethod - Fungsi role dan boleh dikongsi fungsi ini dengan RolePlayer yang lain yang ada contract Role yang sama.

Habis preview 1 :)

Sunday, March 20, 2011

DCI + CQRS = Vaccine Framework

Salam berapa Malaysia

Ok last 2 weeks , aku agak busy developed simple framework , yang aku panggil vaccine framework, apa itu vaccine framework? Vaccine framework mengandungi beberapa combination pattern diantaranya ialah DCI dan DDD-CQRS. Selain dari itu vaccine framework tidak meyimpan current state domain object sebaliknya menyimpan event dalam 2 jenis event, normal event dan snapshot event.

Read dan write totally diasingkan component2 nya. Tiada lagi reference antara aggregateroot ke aggregateroot yang lain sebaliknya reference ini berlaku secara sementara didalam role apabila command di execute. Jadi reference ini hanyalah berada di read domain dan dalam bentuk denormalized.

Terdapat perbezaan ketara antara vaccine framework dengan cqrs framework yg lain seperti ncqrs (.net) dan axonframework (java). First sekali sudah tentu framework tersebut tidak support cara DCI working secara default dan framework2 tersebut semuanya derive current state object dengan replay event, walaupun framework tersebut ada process untuk derive dari snapshot tetapi ianya bukan secara default. Sama ada perlu letakkan configuration berapa bilangan event berlaku dan buat snapshot atau run another thread untuk buat snapshot dan store dlm sequence of event.

Manakala dalam vaccine, setiap event of object akan disimpan hanya kepada 2 jenis table EventSource dan EventSourceSnapshot, dan main event yang akan direplay ialah di EventSnapshotSource.

Keseluruhan application kita akan hanya ada 2 table di write component dan pelbagai table report di read component berdasarkan bagaimana kita nak show information ke user sama ada paparan ke screen atau format percetakan.

InsyAllah, aku dah rewrite sikit mars application untuk POC, mcm maner vaccine framework ini bekerja. masih lagi baby framework, hopefully dapat support 1Malaysia hahahaha .. yeyeye

Monday, March 14, 2011

CQRS - Part 2

Salam 1Malaysia

Minggu lepas coretan pertama berkaitan CQRS dan serba sedikit pengenalan apa itu CQRS. Seperti yang diterangkan, asas paling utama dalam CQRS ialah membezakan process write dan read.

So kenapa perlukan CQRS. CQRS hanyalah pilihan dalam architecture design, bagi developer yang inginkan scalability, performance dan maintainability boleh mencuba CQRS dimana terdapat pelbagai versi CQRS yang boleh dipilih untuk dibuat guideline.

Sebelum diberi nama CQRS, architecture pattern ini dikenali sebagai CQS-DDD dan terdapat kekeliruan di antara CQS - Bertrand Meyer dan CQS-DDD dari DDD group. Walau objective kedua-dua pattern nie sama, dan tak dinafikan CQS-DDD menjadikan CQS - Bertrand Meyer sebagai asas pattern, tetapi CQS-DDD bergerak ke arah yang lebih besar iaitu architecture pattern.

CQS - Bertrand Meyer punya definisi :-

"every method should either be a command that performs an action, or a query that returns data to the caller, but not both"

Jadi CQS- Betrand Meyer punya target pada masa itu ialah supaya satu class/method tidak akan buat2 perkara write dan read dlm class/method yang sama.

CQRS juga mengambil prinsip yang sama, maka perkara pertama yang perlu dipastikan ialah design class/method yanag akan handle concrete kerja. Satau class akan buat command-(write) dan satu lagi class akan buat query-(read).

Begitu juga halnya pada code existing, apa yang boleh dibuat ialah cuba refactor dan pecahkan function2 tersebut ke dalam kategori masing-masing.

Thursday, March 10, 2011

CQRS

Salam 1Malaysia

CQRS Architecture pattern, agak complex jika pertama kali membaca artikel atau mendengar mana-mana presentation berkaitan.

Objektif utama ialah untuk membezakan antara (read) dan (write) domain object. Itu sahaja, cuma untuk mencapai objektif tersebut terdapat beberapa cara penyelesaian yang boleh diguna pakai.

Penyelesaian yang paling umum ialah dengan membezakan proces (write domain object) dan proces (read domain object) menggunakan component yang berlainan.

Ok sebelum itu image dibawah adalah contoh architecture design yang biasa digunakan



Jika diperhatikan process write dan read mengunakan component yang sama dan melalui process yang sama dari client hingga ke server.

Masalah utama ialah untuk ialah scalability dan performance. Umum mengetahui write process adalah lebih lama dari read process, tetapi apabila satu domain digunakan untuk read dan juiga write, ini akan memberikan penalti dari segi performance.

Dari segi database, apabila write dilakukan, sql server akan lock row sehingga process write tadi selesai dan jika pada masa yang sama terdapat client yang ingin membaca data tersebut, client tersebut perlulah menunggu sehingga process tersebut selesai. Untuk sistem yang trafiknya adalah kecil, keadaan ini tidak mengganggu performance tetapi bagi trafik yang besar,peratusan kemungkinan sistem akan crash adalah besar.

So untuk next coretan, insyAllah akan bawa contoh penyelesaian yang boleh digunakan.

Salam 2Malaysia :)