views:

127

answers:

3

I'm beginning a new project and I want to start by modeling the data that the client needs to store. However, I have no idea where to begin. So far, I'm trying to model two simple entities, Event and Address. An Event can have multiple Addresses and an Address can be associated with multiple Events. This is what I have:

public class Event
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public List<Address> Addresses { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public string Street { get; set; }
    public string Zip { get; set; }
    public List<Event> Events { get; set; }
}

However, I ran into a problem when I tried to create the test repositories for these two objects. They have a circular dependency: Event can't populate its Addresses list until Address is fully populated, but Address can't populate its Events list until Events is fully populated. This led to me to believe that I don't know what I'm doing.

I've been reading a lot about POCO, DTO, DAO, and DDD, but these concepts don't make much sense to me no matter how hard I try to understand them. I've only recently graduated from college and I haven't even heard of the term 'domain model' until a week ago.

Conceptually, what I'd like to do is first create classes that represents the types of data I need to store (the Entities I believe). These classes will also contain the validation logic (is this POCO?). After that, I want to set up repositories to access collections of these objects and populate any relationships they may have (for example, Event will get populated with a list of Addresses) [is this persistence ignorance?]. Only after all that's in place do I want to create the database to hold the data (through a DAO? Is a ORM a DAO? How would I use LINQ-To-SQL to do this?). And where does IoC fit into all of this, or does it not fit at all if I know that my backend will never change and I will always hit up only one database?

If it hasn't been obvious already, I'm pretty confused as to where I'm supposed to start. I have a good conceptual idea of what I want to do, I just have no idea how to implement it. Can someone provide me with advice on a good starting point? Thanks.

+4  A: 

Well in the example you have given it seems that the Address should not contain a reference to events, but you will want a repository that can find events for a given address. The address looks to be more of a Value object. There is a book by Eric Evans that parts of are available on-line if you want to review what value objects are and how they differ from entity objects.

As far as IOC containers are concerned they are quite useful in eliminating boiler plate factory code where the factory is responsible for creating your objects for you. When you have an IOC container you the developer ask the container for an instance of the class you need. This eliminates the need for you to write the factory yourself.

Persistence ignorance as I understand it is that the object does not concern itself about persistence and they is where the repository pattern comes in. You use the repository as a means by which to get, save, update and delete objects. The objects themselves do not concern themselves with persistance.

I would look at POCO (Plain old CLR object) as an object that has behavior but does not concern itself with cross cutting concerns. A DTO (Data Transfer Object) is typically an object that has little to no behavior and who's purpose is to carry data from point A to point B. A DAO (Data Access object) is used to access data from the database ie Repository. DDD (Domain Driven Design) is a set of design principles that guide you through a proper design process as you think about your software in terms of the domain you are building it for.

I hope this helps.

Michael Mann
That is exactly what I was going to say. :)
Frederik Gheysels
A: 

As Michael points out, Address is a «Value Object» in many domains, but I'm going to assume that you have perfectly valid arguments for making it an «Entity» (the id) and an «Aggregate Root» (the repository).

I'm an NHibernate user myself, and don't know all the details of Linq-to-SQL. Although NHibernate supports many-to-many mappings, it is strongly suggested that you (if I remember it correctly from Hibernate in Action) include the association class (i.e. a class representing your reference table) in your domain model.

Things gets more explicit, and future properties of the association, e.g. a flag for a primary address, is much easier to add.

With the new model (Event (1) - (x) EventAddress (x) - (1) Address) in place, remember that you must do the book keeping of the bi-directional associations yourself, e.g. following Fowler's master-slave pattern from UML Distilled.

With NHibernate you also tells it which end is inverse (slave), but you'll have to consult the docs of Linq-to-SQL to find out how it does the same trick.

You can read more about master-slave relationships here: http://blog.lowendahl.net/?p=88

Martin R-L
A: 

Don't worry so much about the letters of the law to begin with.

There are a few basic principles that has led to the alphabet soup of patterns and methodologies, and if you stick to these principles your will see that your code gravitates towards at least some of them most of the time.

If you are concerned about patterns and concepts over actually solving your problem, you risk choosing a pattern that is a perfect solution to a different problem to the one you are having.

In the example you are describing, you need to get a list of addresses for each event, and you need to get a list of events for each address.

How can you model that so that the rest of your code, any present and future requirement that your application wll face, can easily and reliably work with these two things? For your particular needs, what would be the best solution?

Think about that first, and you might often find that your solution is similar to a well known pattern.

Console