views:

43

answers:

2

Our core domain so far has an abstraction called PersonName with methods for firstName, lastName, middleInitial etc. As we are expanding the domain to Spain, we figured that they only talk in terms of name, firstSurname and secondSurname i.e. middleInitial etc have no significance to them.

The PersonName interface is currently being used at many places in the current API and the SpainPersonName should also be used at the same places. So, my option is to extend SpainPersonName from PersonName. But, if i do this then I will end up exposing the API for firstName, middleInitial etc which are not applicable for Spain domain.

My question is how best we can refactor the current abstractions still keeping the backward compatibility? Any refactoring or design suggestions are greatly appreciated.

+1  A: 

I am not too sure what your question is. By "to extend SpainPersonName from PersonName", do you mean make SpainPersonName implement or inherit from PersonName?

In any case, let me speculate that the PersonName abstraction might be a flawed one. An abstraction must be widely applicable, at least to the situations where it is applied, right? We Spaniards do not think in terms of first name vs. last name, as you well point out. Maybe the abstraction needs to be rethought. In my experience, an abstraction based on GivenName plus FamilyName is the most widely applicable one, even to Asian cultures where the order of names is not the "usual" one.

Being constructive, I think that you need to map the Spanish first and second surnames to the abstract last name, because that (first and second surnames) is what we Spaniards conceive as our "last name". If you can do that, then you are doing acceptably well.

CesarGon
yes SpainPersonName extends PersonName. And I know the abstraction is broken but it is too late to change it as our customers are already using the existing API. My question is how best we can refactor the current abstractions still keeping the backward compatibility?
Pangea
Well, refactoring something implies changing it! If you cannot change PersonName, then you cannot refactor it. You are stuck with it. The only thing you can do is use it as is and focus on the SpainPersonName implementation. Is that what you are planning to do?
CesarGon
Yes. I am stuck with it for now. So to play well along with the rest of the doamin API, my SpainPersonName should extend from PersonName. So shall I just add the new methods such as getFirstSurname(), getSecondSurname() (ubiquitous language) and just throw UnsupportedOperationException from the methods that are nor relevant to the Spain domain like getMiddleInitial()?Also, what is the ideal way of representing the name abstraction? Like the givenName and FamilyName you are talking about. Can you refer to me some reference docs?
Pangea
To your first question: I would add the methods for first and second surnames, as you suggest, and then throw exceptions for unsupported methods or, even better, return an empty string. After all, an object representing someone with no middle initial should return an empty string for that property, I think. However, I do think that a middle initial makes sense for Spanish names. Maybe they are not as common as in the USA, but middle names do exist in Spain.
CesarGon
Regarding your second question, I don't have any documentation references; I am sorry. That (GivenName plus FamilyName) is the structure that I have been using for ages for global application, with good results. Depending on locale/culture, you can then format them appropriately. A SpanishName, for example, could implement GivenName, FirstFamilyName and SecondFamilyName, and map FamilyName to FirstFamilyName + " " + SecondFamilyName. There is an easy mapping for most of the situations.
CesarGon
So u have GivenName, FamilyName as two separate abstractions? If so I am curious as to what methods do they have?
Pangea
GivenName and FamilyName are different properties (attributes) of the PersonName type. If you were to use C#, for example, you would implement PersonName as an abstract class or interface, and GivenName and FamilyName as properties or methods.
CesarGon
+1  A: 

Sounds like you need to change PersonName to AngloPersonName and create a PersonName interface?

Gary