Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have an User entity that has a Set of Address where Address is a value object:

class User{
    ...
    private Set<Address> addresses;
    ...
    public setAddresses(Set<Address> addresses){
        //set all addresses as a batch
    }
    ...
}

A User can have a home address and a work address, so I should have something that acts as a look up in the database:

tbl_address_type

------------------------------------------------
|    address_type_id       | address_type      |
------------------------------------------------
|            1             |      work         |
------------------------------------------------
|            2             |      home         |
------------------------------------------------

and correspondingly tbl_address

-------------------------------------------------------------------------------------
|    address_id       |     address_description      |address_type_id|    user_id   |
-------------------------------------------------------------------------------------
|          1          |      123 main street         |      1        |      100     |
-------------------------------------------------------------------------------------
|          2          |      456 another street      |      1        |      100     |
-------------------------------------------------------------------------------------
|          3          |      789 long street         |      2        |      200     |
-------------------------------------------------------------------------------------
|          4          |      023 short street        |      2        |     200      |
-------------------------------------------------------------------------------------
  1. Should the address type be modeled as an Entity or Value type? and Why?
  2. Is it OK for the Address Value object to hold a reference to the Entity AdressType (in case it was modeled as an entity)? Is this something feasible using Hibernate/NHibernate?
  3. If a user can change his home address, should I expose a User.updateHomeAddress(Address homeAddress) function on the User entity itself? How can I enforce that the client passes a Home address and not a work address in this case? (a sample implementation is most welcomed)
  4. If I want to get the User's home address via User.getHomeAddress() function, must I load the whole addresses array then loop it and check each for its type till I find the correct type then return it? Is there a more efficient way than this?
share|improve this question
1  
What about users with multiple homes? –  Donal Fellows Nov 12 '13 at 16:38
add comment

5 Answers

I think that the type is not a property of the Address, it's a property of the connection between a User and an Address.

An Address normally represents a specific location in the world, a type would be connected to the use that a User makes of the Address.

An Address might even be used for both Home and Business for some Users. Or be the Home of one User and the Workplace of another User.

So:

  1. The Address should be a Value type.
  2. It shouldn't be connected to the AddressType
  3. For me it would depend on how many addresses the User is expected to have, and how static will the types be.
  4. A kind of Map would be more efficient...
share|improve this answer
    
Certainly seems like the cleanest solution, but since addresses are typically used only once, denormalizing them into the user-address connection is probably the most practical approach in many situations. –  CodesInChaos Nov 13 '13 at 14:24
    
It would depend if you ever need to know who shares an address, or what kind of purposes that address serves. And, of course, if it's important that when you correct and address you only have to do it once. –  Adagios Nov 14 '13 at 14:09
    
I think in these modern times, we need latitude and longitude fields –  Joset Nov 22 '13 at 7:52
add comment

The question I would ask myself, from a DDD perspective, is "does the address know it is a home or business or what have you?"

The answer is likely no. A slightly better model would be to have a user have an addresses collection like you are showing but also add a property pointing at the home / business / primary addresses as required.

One technical note is that, for package delivery purposes you should have an "Is Residential" flag on the address, as well as an "Is PO Box" flag to filter those out as they do materially change how one can deliver things which are the sorts of things an address object should understand.

share|improve this answer
add comment

Does user need more than 3 addresses? Rarely. I recommend to denormalize the collection of addresses.

User will simply have fields address_home, address_work, address_other where all 3 will be of type Address, which will be value type.

This model covers 99.99% of use cases, is much easier to understand, is easily implemented in code and maps much better to both relational and document model.

And if you plan to use relational DB, you can have all data in User table, which will speed up retrieval significantly.

If denormalization is not an option, then I would model the addresses as Map/Dictionary with address as value and either string or some kind of enum as key. The Address would be immutable value object and the relational model will be single table with composite primary key from userId and map's key. Thus, the address itself would not have an identifier. Rest of the table would be data of the address. This still keeps the model simple and easy to understand. But the mapping between dictionary and relational table might not be that simple. But it is still doable.

share|improve this answer
    
well, that's a good solution, but unfortunately it doesn't scale well as most of the time I'm working on that 0.01% where the requirements change dramatically and our clients just come up with new insane requests to add new types. BTW I'm just using the address example coz it's easy to demonstrate the idea without without getting hanged on the code itself. –  Songo Nov 13 '13 at 9:42
    
@Songo what is that 0.01% have in the 4th address? did you really force the business rules to avoid over engineering? –  Serdar Buyuktemiz Nov 20 '13 at 9:53
    
@SerdarBuyuktemiz All engineering is all about compromise. You should always aks "is the added complexity worth it from business standpoint? (eg. will it give you/not loose money) ?" In this example, someone having more than 3 addresses could be extremely rare. Like from 1M people, like 100 could use that feature. But his all depends on what kind of business you do and what business person says. –  Euphoric Nov 20 '13 at 17:49
add comment

What everyone seems to be missing is that a single address can be used by several users.

So you need something like:

User  Usage Addr
   1      1    1
   1      2    2
   2      1    3
   2      2    2
   3      1    1

Id  Number     Street        Town
1   23         Accai Drive   Hoboken
2   15         Wall Street   N.Y.C
3   99         First Street  Armonk       

In this way can share office locations between colleges and home addresses between cohabitants. It also solves the problem of what you put in the "work" address for people who work from home.

share|improve this answer
add comment

Should the address type be modeled as an Entity or Value type? and Why?

I think that address is a candidate for a domain model. It's common for address objects to have validation behaviour. For example, you might want check that certain fields are set or that the postcode is valid prior to setting it. Some might argue that postcode validation shouldn't be done in the address object. This can be debated.

Is it OK for the Address Value object to hold a reference to the Entity AdressType (in case it was modeled as an entity)? Is this something feasible using Hibernate/NHibernate?

I'm assuming that AddressType is defined in your data access layer. If this is the case, then at some point you will want to expose your address in the presentation or service layers. All of a sudden your data layer logic is leaking into presentation and service layers.

If a user can change his home address, should I expose a User.updateHomeAddress(Address homeAddress) function on the User entity itself? How can I enforce that the client passes a Home address and not a work address in this case? (a sample implementation is most welcomed)

I don't think that User.updateHomeAddress(Address homeAddress) is a right way forward. I'm assuming that in your system user plays a major role. I wouldn't pile up user related concerns into a single User class. The more responsibilities you give to the user, the harder it will become to maintain your code.

One of the solutions is to have a command class for updating address.

E.g.

public class UpdateHomeAddressCommand 
{
   private User _user;
   private Address _address;

   public UpdateHomeAddressCommand(User user, Address address)
   {
      _user = user;
      _address = address;
   }       

   public void Execute()
   {
       // Update logic
   }
}

In the example above, I'm using a simple command to update address. If you find that logic for updating home and work address is very similar, than you can move it into an abstract class and then make UpdateHomeAddressCommand to inherit from abstract UpdateAddressCommand.

If I want to get the User's home address via User.getHomeAddress() function, must I load the whole addresses array then loop it and check each for its type till I find the correct type then return it? Is there a more efficient way than this?

Ideally your data layer should return only the data that you need. Otherwise it's unnecessary data travelling over the wire.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.