5

I'm writing a library which includes some wrapper code for some underlying API. In that underlying API, there are two concepts, "foo" and "bar", whose literal meaning in the English dictionary is close to the switching of their meaning in the API. i.e. it uses "foo" for something that's close to "bar" and vice-versa.

(For the curious: It's basically "thread index" vs "thread id" in CUDA. Which one do you suppose is 3-dimensional and which is a linearization of the other?)

Now, in my wrapper code, should I...

  • Stick with their incorrect and confusing terminology?
  • Switch it back, explaining profusely in comments when I'm doing that?
  • Go for other terms, which won't get people mixed-up, but introduce more "concept clutter"?

I'm not asking for input based on your experience with my specific case, but rather with similar situations you may have faced. Also, both a recommendation and unexpected considerations would be useful.

Note: The wrapper code does not wrap all of the underlying API, so that you only ever go through my code. So it is quite possible users will encounter the mis-named terms in other contexts. On the other hand... uses of my wrappers are always through a namespace i.e. quux::foo or quux::bar.

  • Is there any chance that any time in the future someone is going to need to ever use the underlying API along with your wrapper, or consult the underlying API documentation? – DaveG Mar 15 at 20:52
  • @DaveG: Valid question, see edit. – einpoklum Mar 15 at 21:43
  • If it's merely a bolt-on to another API, and there isn't any independent reason to adjust the terminology (such as an integration with a second API that uses conflicting terms), then it'd be better to just belt up and run with the existing terminology. – Steve Mar 15 at 22:18
  • How about combining options 1 and 2 - stick with it, AND comment it? – Robin Bennett Mar 16 at 9:41
  • 1
    @RobinBennett: That is option 1. Of course if I stick with it I'll add a comment somewhere saying "this is the wrong thing to do, but". – einpoklum Mar 16 at 10:03
6

Funny story: years ago I worked at a company that produced a variety of related data products. A lot of the products were closely related, e.g. could be essentially the same product but in a different format.

At one point when I was responsible for generating a product I had to start attending large monthly status meetings where the product manager got updates on the different related products.

Initially I was feeling rather dumb because I only knew my particular area, and the discussions were sprinkled with lots of acronyms and product abbreviations. To make things worse, sometimes the same name was used for different things, sometimes different names were used for the same thing, depending on who was speaking.

But I gradually picked it up, and after a couple of months I was in one of these meetings where the product owner and a dev were having some back and forth, and I suddenly realized that they were talking about different products! They thought they were talking about the same thing, but they weren't! The products were closely related enough that the conversation wasn't complete nonsense, but the terminology was so confusing that no one else was picking up on it!

Another way to think about this: imagine you are someone using your wrapper. And probably looking at some of the API documentation. I know if it was me, and I noticed that the documentation had the definitions for two items reversed, I wouldn't assume that that was deliberate, I'd assume it was a mistake in the documentation, and I'd probably waste time trying to figure out what's going on.

Bottom line: do not, DO NOT reverse the terminology. You will guarantee confusion down the line. If other developers agree that new terminology is required, come up with some completely new names, and document the relationship to the API names.

| improve this answer | |
  • Dasta prodcuts? Also, I neglected to mention you only get to my API through a namespace (edited that in now), so you have to make a bit of an effort to get mixed up. Finally - in your example - the acronyms were arbitrary. It's not like one person "had it right" and another "had it wrong"; and in my case, there is a right and a wrong. But, ok, point taken. – einpoklum Mar 15 at 22:48
  • 1
    @einpoklum and yet, apparently the original devs of the API had a different idea of what was right and what was wrong. – DaveG Mar 15 at 22:56
  • They were in a hurry, and the they were committed to backwards compatibility. And you know what a name switch, as opposed to a name change can do to the volume of user issues with your library/framework... – einpoklum Mar 15 at 23:06
1

Try to see if you can talk to the onces that needs to use your service and do whatever they want. Don't force change anything yourself.

I sort of have the same concept with the dimensions of a book (height/width/depth) The warehouse assumes the book is lying down and the sales people assume the book is standing in a bookshelf.

| improve this answer | |
  • 1
    Ah, but it's a public-use library. Still, if I had specific key users, this would be good advice, so +1. – einpoklum Mar 16 at 11:37
1

I have somehow come across this problem, what feels like a ridiculous number of times.

My approach, is mapping the various logics to where the names are still correct, but make it clear that weird things are happing:

Assuming the external API I use has:

class FooBar 
{
  string foo;
  string bar;
}

and I need to call them from the public layer, I might define them in a way that says this is a business representation

string businessFoo;
string businessBar;

And then use a mechanism to map them (AutoMapper for example):

var objectToSave = Map(businessFooBar, fooBar); // return FooBar and sets Bar from businessFoo,
// and Foo from businessBar
callingApi.Save(objectToSave);

I feel this keeps my areas of concern separate, the business layer can deal with business language and keeps terms sane and distinct.

It also means for Unit testing I can check that the maps are not backwards:

var result = Map(businessFoobar, FooBar);
Assert.Equal(businessFoobar.Foo, FooBar.Bar);

It might not be perfect, but it avoids further muddling terms.

| improve this answer | |
  • In what way does adding a "business" prefix tell you "this is what I get, and what I expect"? Also, I don't quite understand what the combined "fooBar" signifies. – einpoklum Mar 16 at 18:54
  • Tried to clear it up, the idea of the 'businessFoo" is that it would be a name that explains it's a business concept, application name, or maybe source of the concept: "windowsBar", "chromeFoo", "DateStringISO8601". (Finding a good term is proving difficult") – AthomSfere Mar 16 at 19:08
  • 1
    Ah, ok, now I get it. Unfortunately, in my case the terms also feature prominently in function names. – einpoklum Mar 16 at 19:11
  • Addendum: I've also done the: ` externalApi.Method(businessObject.ToApiObject()) `; it's saved my sanity when I was tying 2 or 3 applications together which used the same, or similar names to describe different things: e.g. A Plan of Plans for customer contract plans... – AthomSfere Mar 16 at 19:17
0

Definitely switch the terms so that they make sense. If you're already building a Façade, you might as well make it an Anti-Corruption Layer, too.

| improve this answer | |
  • 1
    And what if someone is using the Facade, but encounters a question or problem that requires looking at the documentation for the underlying API? And has to deal with the switched concepts? – DaveG Mar 15 at 20:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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