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.

First, some background. I have an application that requires the use of several external geocoding providers which I don't control. It uses a central service layer inside the application to dispatch to the appropriate provider.

I have a number of classes that are arranged in this way:

  • GeocodingService: Responsible for dispatching a request to geocode something to an appropriate provider.

    • Has one public method, geocode, that accepts a GeocodingService::Request and returns a GeocodingService::Response.
    • Each response includes: the latitude of the geocoded query, the longitude of the geocoded query, and a list of address components for the address where the query was found (e.g., an address component for "123", one for "Main Street", one for "Paris", and so on).
  • GeocodingService::AddressComponent: A single segment of an address that contains the segment's name, its abbreviation, and its kinds. For example, France has a name of France, an abbreviation of FR, and is a country and a political segment.

    • AddressComponent is responsible for checking that the types an instance is set with are not outside the boundaries of certain tracked types.
  • Address: Domain model for addresses, containing both a preferred mailing address (a list of string lines) and a list of address components (a list of GeocodingService::AddressComponents).

My question is: where should AddressComponent live -- as a service class (like it does now), or with my other domain models?

  • If it lives in the service, then life is straightforward. But that seems wrong, because now a domain model has to depend on a service's definition of an address, and it seems like they should be independent.

  • If it lives as a full-fledged domain object, then doesn't that mean that the service is now coupled to a domain object? That also seems undesirable.

How do I resolve this impasse?

share|improve this question
add comment

2 Answers

Just because AddressComponents are inferred from external data provided by a service doesn't mean they aren't first class domain objects in your domain model. Imagine you write another application in the same domain - wouldn't it be nice if you could reuse your domain layer without having to worry about Services ? I mean, the new application could get AddressComponent data from anywhere, its own database for instance. An AddressComponent wouldn't necessarily be linked to a Service.

So I'd choose option 2, and if you're concerned about your service instantiating a domain object, maybe you could introduce another object that does the creation - a Factory for instance.

share|improve this answer
add comment

You need either an Adapter or Builder to construct your Address domain object from the GeocodingService::AddressComponent(s). This is the point where you loosely couple the components while maintaining separation of concerns and cohesiveness.

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.