Monday, November 09, 2009

Design application - letakkan behaviour mencorakkan design anda dan bukan data

Kena ingat bila design yang penting bagaimana design tersebut menampung keperluan behaviour object2 tersebut dan jgn terlalu ambil berat bagaimana data itu di tunjukkan

Cuba kurangkan penggunaan Inheritance - Inheritance also anti pattern

Next target ialah untuk cuba design menggunakan composition/association dan elakkan terlebih guna Inheritence.

Saturday, November 07, 2009

Setter dan Getter anti pattern

Sekarang aku dapat merasakan kenapa public Setter dan Getter anti pattern...

Thursday, November 05, 2009

Berubah dari pemikiran CRUD ke DDD

Ada diffrent code sebegini?


var teller = s.Get(tellerId);
teller.TotalCashInHand = TotalCashInHand - amountToTransfer

dan lagi satu

var teller = s.Get(tellerId)
teller.DeductCashAmountWhenAmountTransfer(amountToTransfer);

Code atas tu kita panggil car CRUD dan yang dibawah di panggil cara DDD;


Menggunakan AggregateRoot collection untuk add entity/value object

Persoalan yang timbul bagaimana penggunaan sebenar child collections dalam AggregateRoot (AR). Pemahaman aku sebelum ini terlalu ekstrim dimana child collection itu mesti digunakan sama ada untuk add dan juga fetch child item (lazy load). Pengalaman mengajar untuk lebih flexible dalam menentukan penggunaan child collections dalam AR.


Aku bawa satu contoh, didalam library/Book Store system ada satu features yang kita panggil "Lend Book". Bagaimana kita hendak model kan ini.

BookStore 1--0..* AvailableBooks

Didalam sebuah book store akan ada 0 atau lebih Books. Jika kita nak menambah collection buku didalam book store kita akan buat begini:

var bookStore = s.get(bookStoreId);
bookStore.AddNewBook(new Book{ .. });

So bagaimana pula jika kita hendak lend book dari book store?. Oleh kerana book ialah entity dibawah AR book store maka segala aktiviti berkaitan buku sama ada command dan query pelulah melalui AR BookStore (It rules AR) . Jika dahulu aku akan buat begini:

var bookStore = s.Get(bookStoreId);
bookStore.Lend(bookId,customer);

Code didalam BookStore

public void Lend(Guid bookId,Customer customer)
{
var book = AvailableBooks.Where(c=>c.Id == bookId).SingleOrDefault();
BookLendToCustomers.Add(new BookLend{ Book = book, Customer = customer});
}

Ok code ini tiada masalah, malahan follow apa yang disuggest oleh DDD team, tetapi aku akan menghadapi performance problem jika dalam book store tersebut mempunyai 100000 buah buku. AvailableBooks collection akan load semua buku kedalam memori dan akan buat memory query untuk dapatkan buku tersebut berdasarkan bookId (bahasa bercampur-campur book/buku).

Jadi cara aku skrg lebih flexible sama ada membenarkan query ke book entity atau inject domain event kedalam Book store.

Option 1

var bookStore = s.Get(bookStoreId);
var book = s.Get(bookId);
bookStore.Lend(book,customer);

Option 2

var bookStore = s.Get(bookStoreId);
bookStore.Lend(bookId,customer);

Code didalam book store

public void Lend(Guid bookId,Customer customer)
{
var event = new BookQueryEvent{ BookId = bookId}
DomainEvent.Raise(event);

var book = event.Book;
BookLendToCustomers.Add(new BookLend{ Book = book, Customer = customer});
}

Code domain event akan diinject menggunakan any IoC library seperti castle,autofac,structuremap etc

Saper sudi share..pendapat