views:

67

answers:

1

I'm designing a larger enterprise architecture and I'm in a doubt about how to separate the models and design those. There are several points I'd like suggestions for: - models to define - way to define models

Currently my idea is to define:

  1. Core (domain) model
  2. Repositories to get data to that domain model from a database or other store
  3. Business logic model that would contain business logic, validation logic and more specific versions of forms of data retrieval methods
  4. View models prepared for specifically formated data output that would be parsed by views of different kind (web, silverlight, etc).

For the first model I'm puzzled at what to use and how to define the mode. Should this model entities contain collections and in what form? IList, IEnumerable or IQueryable collections? - I'm thinking of immutable collections which IEnumerable is, but I'd like to avoid huge data collections and to offer my Business logic layer access with LINQ expressions so that query trees get executed at Data level and retrieve only really required data for situations like the one when I'm retrieving a very specific subset of elements amongst thousands or hundreds of thousands.

What if I have an item with several thousands of bids? I can't just make an IEnumerable collection of those on the model and then retrieve an item list in some Repository method or even Business model method. Should it be IQueryable so that I actually pass my queries to Repository all the way from the Business logic model layer? Should I just avoid collections in my domain model? Should I void only some collections?

Should I separate Domain model and BusinessLogic model or integrate those?

Data would be dealt trough repositories which would use Domain model classes. Should repositories be used directly using only classes from domain model like data containers?

This is an example of what I had in mind: architecture figure 1

So, my Domain objects would look like (e.g.)

public class Item
    {
        public string ItemName { get; set; }
        public int Price { get; set; }
        public bool Available { get; set; }
        private IList<Bid> _bids;
        public IQueryable<Bid> Bids
        {
            get { return _bids.AsQueryable(); }
            private set { _bids = value; }
        }
        public AddNewBid(Bid newBid)
        {
            _bids.Add(new Bid {....
        }
    }

Where Bid would be defined as a normal class.

Repositories would be defined as data retrieval factories and used to get data into another (Business logic) model which would again be used to get data to ViewModels which would then be rendered by different consumers.

I would define IQueryable interfaces for all aggregating collections to get flexibility and minimize data retrieved from real data store.

Or should I make Domain Model "anemic" with pure data store entities and all collections define for business logic model?

One of the most important questions is, where to have IQueryable typed collections? - All the way from Repositories to Business model or not at all and expose only solid IList and IEnumerable from Repositories and deal with more specific queries inside Business model, but have more finer grained methods for data retrieval within Repositories.

So, what do you think? Have any suggestions?

+1  A: 

I don't think that forcing such design in each and every application in the enterprise is a good idea in the first place. It is very specific. How can you predict what will be the needs of individual applications?

Second, what you presented is really not a domain-driven design. It looks like Microsoft-blessed n-tier approach. What you have is data structures in all 3 layers. Why separating your 'domain model' from business model? Rich domain model containing both data and behavior should be enough for most of complicated systems. View model can be built on top of this model (simple, classic solution) or directly from database (CQRSish solution). The latter seems to work better in complicated scenarios.

You ask item has thousands of bids. Well, maybe bid is an aggregate root (a domain concept you are missing) and shouldn't be contained in any collection.

My advice would be, if you want domain model, stick to DDD modeling practices (Eric Evans, Jimmy Nilsson) and don't follow App Archi Guide literally. If necessary, add a little bit of CQRS to your solution to clean the model from UI related concerns. This way you avoid all sorts of problems related to collection handling.

Szymon Pobiega