12

As an example, say you are writing an app in Java.

Your app communicates with an API server written in Python.

The Python server communicates with an SQL database.

You also have a website for your app written in JavaScript.

With 4 different languages, it's easy to end up repeating essentially the same data structures 4 different times.

For example, a User type might look like this (pseudocode):

type User {
  integer id;
  string name;
  timestamp birthday;
}

Every part of the project would need some kind of representation for User. The Java and Python parts would need two different class declarations. The database would need a User table declaration. And the front end site would need to represent a User too.

Repeating this type 4 different times really breaks the Don't-Repeat-Yourself principle. Also there is the problem that if the User type is altered then these changes need to be repeated in every different part of the project.

I know that Google's protobuf library offers a kind of solution to this problem wherein you write a datastructure using a special syntax, and then the library generates a structure declaration for you in multiple different programming languages. But this still doesn't deal with the issue of having to repeat validation logic for your types.

Does anyone have any suggestions or links to books/blog posts about this?

  • This is one reason why a lot of folks have been moving all their development to JavaScript. Works on the client (web, ionic for mobile, electron for desktop), server (node), database (MongoDB). – Paul Feb 9 '18 at 3:32
  • 3
    One can share the same data structures if the back and front end use the same language. Your not repeating yourself if it’s using different code bases. Use tooling to generate the classes from xml schemas or Json strings from the different dev platforms. – Jon Raynor Feb 9 '18 at 4:42
  • 5
    Repeating this type 4 different times really breaks the Don't-Repeat-Yourself principle. Not It doesn't. You have 4 different systems that does different things. You are taking DRY too far. To my experience, the Sort of reusability you want to do is the seed of the evil, because introduce tight coupling. That even worse than having repeated User 4 times in 4 different languages. In distributed environments, coupling is a problem. DRY is not. – Laiv Feb 9 '18 at 7:34
  • Don't have the time for an answer: Depending on your needs you could try to formulate the rules for validation using e.g. OWL (so build an ontology). Validation rules then become "data" which can be used at the necessary points. Changing the rules can then be done at one central place. – Daniel Jour Feb 11 '18 at 10:59
12

You do not. Or really, you should not.

If you think of app, your server and your website as separate contexts, then it makes sense there to be duplicate structures. Reasons why it might be a good thing:

  • The structures are similar, but not same. Even if 90% of structure is same across all contexts. Its the 10% that will give you massive headaches.
  • Patterns and implementations might be different. When different languages and frameworks are used, it becomes way too difficult to have same implementation across all of them
  • The shared structures become a dependency, that needs to be managed. Having shared dependency greatly complicates development, as change that is great in one context is abysmal in another. So lots of effort is needed to coordinate development of this shared dependency
  • Different contexts have different deployments. Even if you do manage to share same data structures and same validation code across all of the contexts, it can still happen that new version of one context is deployed while others are on old version, so situations where there is desynchronization in versions still need to be addressed

While DRY principle is amazing, I think sharing data structures across contexts or layers creates more problems than it solves. Especially if project grows big enough that different people are working on different contexts.

5

I think @Euphoric listed a couple of good reasons not to duplicate your code. However, if you must do so I'd recommend using code generation.

Find the canonical form of the data

To do so effectively you must first discover what is the canonical form of the data. Is it your SQL schema, or classes in your Java program?

Derive (automatically) the other forms from it

After that, devise a way to generate all the other forms from the canonical one. For example, assuming your canonical form is the SQL schema, you can generate JavaScript, Java, and Python code from that easily (SQL is easily parsed and a good candidate for the canonical source).

Accommodate differences

It should be easy to mark sections of the generated code as "don't touch" - this way you'd accommodate required differences between all the different representations (for example: the custom code you wrote for your JS frontend and Java backend) that need to be preserved across regenerations.
Take an example from Git; when it opens an editor to let you enter a commit message the file already contains some text, but it has the # -------- >8 -------- marker to know where your content ends, and where its automatically generated text begins.

Still, if you can - avoid such duplication. It is a PITA, even if most of your code is automatically generated.


This answer is a bit of a story time instead of "here's some best practices" one - what I described is exactly what I once did when I had the same problem as you and needed to have the same data represented in different parts of the system (or, rather, in two different systems).

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.