Wednesday, June 18, 2008

Forkwind Part 3: Creating the domain model :

This is the 3rd part of our forkwind implementation. If you are not aware of the master thread and forkwind, please go here first.

Introduction

After discussing about modules and assemblies in part 2, we can again get our hands dirty with the code. Once the project skeleton up , the next thing is to implement the model or the domain model.
Technically the domain model has nothing to do with code but this is something you should be able to generate while thinking about the problem or discussing with the customer. For instance, the Forkwind application is a solution for tracking orders from suppliers and customers. So considering these, what concepts are being visualized in our minds ? We have a supplier and we have a customer. We also have orders. Since we have orders, we have also products. This is a very basic abstraction but it is extremely useful. We should also be able to tell the relationship type between these entities. For instance a supplier has many products

You should be able to do this just by thinking or with a piece of paper and pen. The rest of the implementation is just filling the gaps and details.

Forkwind Domain Model:

Since we have modelized the basics, we can fill the gaps by simply scetching an informal class diagram. I use a small program called dia but a piece of paper is just good. No need for fancy uml software.

Here's my diagram:



If it it doesn't make sense to you you can follow it from the source where I posted at the end of this post.
Here's my solution explorer:


When you look at the code you will see all properties marked as virtual. This is due to we will use NHibernate in the next posts and in order to do lazy loading properties must be virtual. Don't worry we will come to that.

Let's go each of these classes briefly:

DomainObject: This is the base class for all our entities. This is the place we can put common code. Currently it has an Id field. This for mostly nhibernate but it is practical to have an Id for each of our domain entites (I would use a guid type for an object database like db4o). It's type is long.

Company: This is the base type for suppliers and customers since we assume they are companies. It has general properties like Name, Adress etc. A company has one address.

Customer : This is derived from company and represents our customers. Also a customer has many customer orders.

Supplier : This is dervied from company and represents our suppliers. Also a supplier has many supplier orders and a supplier has many products.

Product: This represents a product type actually not the product itself. This is a common confusion when developing our models. Our product has a property called Quantity. But for an instance of the product the quantity would be always one. But in general we model the product type as model. A product can belong to many categories and a product belongs to a supplier.

Category:
This is for categorizing our products. It is hierachical. A category has one parent category and a category has many children categories and a category has many products.

Order:
This is the base class for SupplierOrder and CustomerOrder. Why I seperated those into two ? This is completly with instict. I just presume they might have different behaviorus and properties depending on your company policy. An Order has many OrderLineItems.

SupplierOrder:
Derived from Order. A SupplierOrder has a supplier

CustomerOrder:
Derived from Order. A CustomerOrder has a Customer

OrderLineItem:
This represents an each line in our Orders. An OrderLineItem has a Product.

OrderStatus:
This is basically an enum represents the state of our orders. It can be pending (by default this is set in the Order's constructor), cancelled or completed

Address: Represents an address used by a company.

This is pretty much about our domain model. It looks okay to me and it is ready to be cooked. Sure we might refactor it. One thing you should notice, we haven't done anything about database. Because this is domain driven design, it is the domain that derives our design and we completely ignore the database unlike the traditional approach.

The code is here. In the next part Forkwind Part 4: Domain Driven Design and Record Driven Design we will get into some theory and investigate why we have chosen domain driven design over a database driven design. Till then stay tuned!




1 comment:

GR Brains said...

Thank you for sharing this post about the best techniques for Symfony Development, This is very useful for Symfony Development and Symfony Development Company. Thanks again :) Symfony Development