02 fevereiro 2009

#1 Principle of Object Modeling & Design of Domain Models

In OO if you want to execute an action over an object you don’t explicitly execute that action, but you ask an object to execute that action for you. This in contrast with procedural languages.
Well it may not be number one, but I see so many people confused about where to put a business method when building a Domain Model that this post is just a reminder of basic OO principles.
Say we have the following business activity:
“Pay an Order by Credit Card”
Seams easy. So the programmer start coding immediately in C# the activity using practices that I see so often (I’m sure you do to).

Example of a procedure implementing this activity using non OO methods:
1: public void PayOrder(OrderData aOrder, CreditCardData aCreditCard)
2: {
3:     try
4:     {
5:         // start transaction
6:         double ammount = this.CalculateOrderAmmount();
7:         PaymentData aPaymentData = this.MakePayment(ammout, creditCardData);
8:         // commit transaction
9:     }
10:     catch (Exception ex);
11:     {
12:         // perform clean up
13:     }
14: }
The problem here is that you have no objects (OO way) apart from the current object (this), that might be a singleton class exposing business services to an upper layer. Let’s say it is the OrderBC. BC from business component.
Both orderData, creditCardData and PaymentData are just data structures that hold data (a class with properties only and little to now behavior is nothing but a structure like a record was in Pascal. We now call them DTO’s). Some of us implement this data structures using DataTables other using structured Classes. Furthermore business rules for payment are entirely coded both in the function CalculateOrderAmmount and the procedure Pay.
Now take for instance the OO version of this:
1: public void PayOrder(Order aOrder, CreditCard aCreditCard)
2: {
3:     try
4:     {
5:         // start transaction
6:         aOrder.MakePayment(aCreditCard);
7:         // commit transaction
8:     }
9:     catch (Exception ex);
10:     {
11:         // perform clean up
12:     }
13: }
So here we have two first class objects, aOrder and aCreditCard. Remember the definition of this activity?
“Pay an Order by Credit Card”
So instead of having functions calling functions or procedures of some mega component we ask the Order to make the Payment.
I understand that this principle has been forgotten by many not because of them, but because of how we have been evolving around enterprise architectures built to cope with data access and storage in relational databases. Not only that, but with external services also.
But now you lucky ones that are using Object Relational Mappers and can apply OO principles do design the Business Domain are reminded.
Stay cool.

Sem comentários:

Enviar um comentário