# How does one choose where to place logic which converts data between two formats/representations?

Suppose I have two "modules", A, and B (I'm choosing not to use classes, because you generally can't create an instance of a module, which makes this question simpler). These modules contain methods suited for dealing with the same particular type of (arbitrary) data. Crucially, the representation/format of this data is different between A and B.

At some point we have a piece of data which is in a format which one of the two modules "understands", but the other does not, and the programmer has a desire to "convert" the piece of data from one representation to another.

For the sake of example, lets say we have data which is in a format that module A understands, but module B does not. On which of the two modules should I place the method that converts the data from "A representation" to "B representation"?

To explore the question a bit, it seems that we have to choose one of the following to be true:

• A given module knows how to convert data from another format, to the format it understands
• A given module knows how to convert data from the format it understands, to another format

In either scenario, in order for a conversion to take place, a given module must contain information about the data representation/format of a module other than itself in order to perform a conversion. From an OOP design or separation-of-concerns perspective, this seems like a bad idea.

Is introducing a third module, C, which understands how to convert the data between different representations, a more sane way to approach this?

• If you find it necessary to spend a rep point on downvoting this question I'd appreciate it if you take the time to explain why. Dec 17, 2020 at 19:01
• Topics like this are best answered for real cases with context. In the current form, the question is IMHO too general and unfocussed - any kind of place, either "A, B, or C", or a combination of two, or all 3 can be "the right" place, depending on the circumstances. Dec 17, 2020 at 21:01

It is usually better to have a module or class convert from another format to the format it understands.

While one can argue that all getters and setters are evil, it is clear that setters are more evil and problematic. Setters might

1. cause concurrency issues
2. throw IllegalArgumentExceptions (or similar)
3. have complex data validation issues (nulls, valid birthday, etc...)
4. leave the result in an indeterminate state.

Calling lots of setters on an different class or module that you don't fully understand is rife with dangers, since you don't know all the complexities. Getters rarely have any of these issues. When you convert from a B, you are only calling its getters. So, the best approach is something like (Java syntax, yours may vary)

public static A fromB(B b);   or

public A(B b)

True, there may be data validation issues with A, but A already knows about them. The programmer only needs have deep knowledge about A, not A and B.

Next, consider what happens when B changes.
They add a new required field, APIVersion. If A is converting to a B, A must change. And you are likely to forget about it.

But, if A is converting from a B, it might be able to stay the same. Depends if A cares about APIVersion. If it doesn't care, you leave it alone. If it does care, you should have already opened up an issue to add APIVersion, and it falls into that work naturally.

That said, if you have a lot of things to interconvert, A-Z, this becomes very messy.

An alternative approach is to have everybody understand some common intermediate data representation, say XML, JSON, CSV, a database, whatever makes sense for your stuff. Then, for your conversion, do something like:

...