0

I am working on a mobile application, and I want to plan a separation between the model layer that represents a user (that comes from the server) and the "applicative" user that has the same fields but additional parameters. The goal is to make sure that a change in the model layer will not harm the applicative user.

One approach I can think of is to have a User class in the model layer that is used to represent a user that comes from the server. It has the following fields:

class User {
  private String id;
  private String name;
  private String email;
  // many other fields
}

In the applicative layer, I have an ApplicativeUser class that has the same parameters as the User class and additional parameters:

class ApplicativeUser {
  private String id;
  private String name;
  private String email;
  private Color color;
  // many other fields
}

In this approach, I duplicated the objects, In my case User have many other objects so I need to duplicate all of them.

Another way is to have getters for each field in a wrapper class:

public class UserAccessor {
  private User user;

  public String getUsername() {
    return user.getUsername();
  }

  public String getEmail() {
    return user.getEmail();
  }

  public String getId() {
    return user.getId();
  }

  // other getters for other methods in the User class
}

But It also will contains many getters..

What do you think about the solutions? Do you have any other suggestions for separating the model and applicative user?

Thank you!

5
  • 1
    Can you clarify what "applicative user" is? Did you mean application user? Commented Dec 29, 2022 at 13:21
  • 1
    Can you describe how User and ApplicativeUser are used by the system? Commented Dec 29, 2022 at 13:23
  • @GregBurghardt User is the object that represents the same object provided by the backend. ApplicativeUser is the same user but with additional fields that have been used by the app. For example Color it's a property that only the app matter about.
    – Maor
    Commented Dec 29, 2022 at 19:50
  • Ok, I guess I'm getting hung up on the meanings of things. Are you using "applicative" to mean "relating to or involving the application of a subject or idea; practical or applied", or is it a misspelling of "application"? Commented Dec 29, 2022 at 20:00
  • 1
    @GregBurghardt It may be my mistake in the explanation, I mean the user in the layer of the application
    – Maor
    Commented Dec 29, 2022 at 20:02

1 Answer 1

1

The goal is to make sure that a change in the model layer will not harm the applicative user.

Then just dupe the fields. We spend a lot of time learning how to inherit and reuse code. That's important but it's hard won knowledge so once we know how to do it we tend to over do it.

The acid test is change. If a change in the model user fields should not automatically result in a change in the applicative user fields then just use your first solution.

It's duplication of ideas that should be avoided not duplication of code. For example, if x=1 and y=1 you have duplication. But if x and y represent two different ideas (usually different directions) they should not be de-duplicated into one just because they happen to have the same value. That's why change makes a good way to test this. If changing x means changing y then they might actually be two names for the same idea. Which would be true if it turned out we were talking about a square.

Your second solution is composition on a data only object. It seems to hide the dependence but it's still dependent. You still need setters or some construction. But mostly if User gets renamed, removed, or restructured UserAccessor will be impacted. And what exactly did the second solution give you that you needed? Changes to User fields are not being reflected in UserAccessor for free. You'd need to update UserAccessor. You could do this. But I don't see why.

If you wanted changes in the fields in User to be reflected automatically in UserAccessor then use inheritance. However, that means your fields are unstable and all of your using code will need to be updated after a change. I generally prefer composition to inheritance. But that's when we're talking about behavior objects. This is old school single data inheritance.

If you want the using code to adapt to field changes consider dumping these key value pairs in a LinkedHashMap=. It's far more flexible than making a Data Transfer Object who's fields are subject to change and avoids resorting to reflection to interact with it. Yes it means getting field names wrong is no longer a compiler error but now-a-days we have automated testing. Use it. With this you can construct the fields in stages and let each stage change on it's own.

But again, if you don't need field changes to automatically propagate just go with your first solution. It's simple. That's a good thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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