Customer customer = new Customer();
customer.CustomerID = 8888;
customer.FirstName = "Serena";
customer.LastName = "Yeoh";
customer.Save();
In the above example, we assign values to the properties of the object (data) and we call its Save() method (behavior) to persist the information. However, after being exposed to layering and Serviced-Oriented Architecture (SOA), I have adopted a practice where I usually separate data and behavior from objects like the above.
I will have Entity objects that contain no methods but only properties to carry data across all the components in my layers. I know in some practices, Entities can have methods and Data Transfer Objects (DTO) are used for transporting data. However, I do not follow such practice because I find it tedious to maintain 2 sets of almost similar classes and I would like to cut the performance & maintenance overhead.
So with my persistence logic isolated to data access components and processing logic moved to business components, the code will look like:
Customer customer = new Customer();
customer.FirstName = "Serena";
customer.LastName = "Yeoh";
// Call business component.
CustomerComponent bc = new CustomerComponent();
bc.SignUp(customer);
and in the SignUp() method in the business component
// Call method in data access component.
CustomerDAC dac = new CustomerDAC();
customer = dac.Create(customer);
The call to the Create() method will persist the customer information into a database table and return its CustomerID back to the Customer object. There are also methods such as Update, Delete and Select to perform other respective functions.
With this design, we can also compose few DACs together i.e.
UserDAC userDac = new UserDAC();
CustomerDAC custDac = new CustomerDAC();
using(TransactionScope ts = new TransactionScope(TransactionScopeOption.Required)
{
userDac.Create(user);
custDac.Create(customer);
ts.Complete();
}
In the above example, we call respective DACs to create an entry in the user identity store (for login) and an entry in the customer table (for profile) - both wrapped in a transaction scope. You can observed a full implementation of such design pattern used in Layered Architecture Sample for .NET.
Although, this is my primary practice, I have always wondered whether I could make it look better. For example, I have encountered scenarios where developers are unsure which DAC to use for which Entity and also finding it hard to find a good naming convention to associate DACs to Entities (I recommended the DAC suffix, "Data" is not recommended because it can easily be misunderstood as DTOs i.e. CustomerData).
Since Extension Methods were made available in .NET, I have thoughts of using it to improve this scenario. Extension Methods were introduced to enhance the LINQ developer experience where it allows us to 'extend' the functionality of a class. Somehow, I noticed that Extension Methods were only used for performing technical logic but not application logic. For example, a common use of Extension Methods can be adding extra functionality to a String or List. You can read more about Extension Methods here.
I am thinking with Extension Methods, I can create my data access component as a data persistence extension class like the following:
public static class CustomerDataExtensions
{
public static void Create(this Customer customer)
{
// Code implementing INSERT logic.
}
}
I can then use it to allow me to persist my Customer object like the original OOP style.
Customer customer = new Customer();
customer.FirstName = "Serena";
customer.LastName = "Yeoh";
customer.Create();
The beauty of this is that I don't even need to worry about returning the CustomerID to my object because it can be automatically assigned in the extension method. I can also have a Load extension method that allows me to do something like this:
// The extension method.
public static void Load(this Customer customer, int customerID)
{
// Logic to SELECT customer from database and assign value to properties.
}
Usage:
Customer customer = new Customer();
customer.Load(8888);
In my opinion, this looks so much better and more meaningful. Not only that, I could still maintain code separation between the Entity and the data persistence methods. I am still early into this and not sure whether such concept will cause any problems. I would definitely want to explore further into the use of Extension Methods.
What do you think?
No comments:
Post a Comment