DDD “View Objects”?

后端 未结 4 702
情歌与酒
情歌与酒 2021-02-14 18:01

Given an application that involves, say, Companies, I might have a Company class. I will have a data access layer that populates a List . However, there will be

相关标签:
4条回答
  • 2021-02-14 18:22

    This is what is typically known as a "view model" or a Data Transfer Object. You may not want your view to have access to the entire data tree exposed by your domain model. Especially if exposing your domain model means that your view will have to dig deep into your object graph to pull the data it needs, a View Model can make alot of sense to simplify working with the model objects. In your case, if you are simply pulling direct properties off of the model object, it would make sense if you want to hide the extraneous data not needed by the rest of your domain model.

    0 讨论(0)
  • 2021-02-14 18:35

    That sounds like a reasonable approach to me.

    Later on, if the customer comes to you asking for your SearchResult to display something unrelated to the Company model - something crazy like the number of nearby ice cream shops you'll have a much easier time appending this to your CompanySearchResult than your domain object.

    0 讨论(0)
  • 2021-02-14 18:40

    The approach you suggest can quickly increase the number of DAO:s you need to create and become a maintenance nightmare. The approach that several ORMs take is to proxy the data access, so your data access layer will return a list of interfaces, and the database call will be postponed until you invoke the data accessor, for instance

    list.getCompany(1).getName()

    . This is call lazy loading. You will still need to make a trade off between making many small or fewer big queries. This type of tasks is one of the strengths of ORMs, you can usually ask your ORM to prefetch parts of the object graph which you think will be used, and leave out other parts.

    0 讨论(0)
  • 2021-02-14 18:48

    I use a crumble of the entity attributes. For example:

    // interface for "ID" attribute of Company entity
    public interface ICompany_ID {
        Guid CompanyID{get;set;}
    }
    // interface for "Name" attribute of Company entity
    public interace ICompany_Name {
        string Name{get;set;}
    }
    // interface for "Logo" attribute of Company entity
    public interface ICompany_Logo {
        byte[] Logo{get;set;}
    }
    
    // interface for all attributes of Company entity
    public interface ICompany : ICompany_ID, ICompany_Name, ICompany_Logo { }
    
    // base class for classes based on Company entity
    public abstract class CompanyBase : ICompany_ID {
        // implementation of ICompany_ID interface
    }
    
    // class for all attributes of Company entity
    public class Company : ICompany {
        // implementation of ICompany interface (all attributes)
    }
    
    // class for Company name lookup
    public class CompanyNameLookup : CompanyBase, ICompany_Name {
       // implementation of ICompany_Name interfade
    }
    

    This crumble allow me to work with different attributes of different entities and all is type-safe. however, your data-layer must support this scenario.

    The next way is dynamic creation of lookup classes, but it is much more complex. On the other side, it is much more flexible.

    EDIT: Then the selection can be for example:

    var companies = (from c in db.Table<ICompany>()
                     order by c.Name
                     select new CompanyNameLookup { ID = c.ID, Name = c.Name }
                    ).ToList();
    

    or for danymicly created types:

    var companies = (from c in db.Table<ICompany>()
                     order by c.Name
                     select DynamicTypeFactory.New<ICompany_ID>( c.Id ).And<ICompany_Name>( c.Name ).Create()
                    ).ToList();
    

    The DynamicTypeFactory is class with static method New and fluent interface for danymic creation classes at run-time.

    0 讨论(0)
提交回复
热议问题