1

Let's say I have an which is loosely can be represented as:

    public class AnObject{
        public AnObject(String name, String value, UUID id) {
            this.name = Objects.requireNonNull(name);
            this.value = value;
            this.id = id;
        }

        final String name;
        String value;
        UUID id;
    }

Now, willing to limit null usage, I would naturally have 2 variations of it, one for Database (with all its non null constraints, below), and one which will be instantiated at run to be sent to some remote resource (nullabe, above). The one to be sent to the remote resource, have the same fields, but they can be nullable. So we have:

    public class AnObjectDBRow {
        final String name;
        final String value;
        final UUID id;

        AnObjectDBRow(String name, String value, UUID id) {
            this.name = Objects.requireNonNull(name);
            this.value = Objects.requireNonNull(value);
            this.id = Objects.requireNonNull(id);

        }
    }

When I receive my object from Database, I am sure to have a non-nullable version, but when I send it to a remote resource, I can omit nullable fields.

Question: given that this obviously doubles the number of classes to declare and to maintain, is that a good idea? What's the best way to represent this in java?

  • This might be more suitable for StackOverflow than SoftwareEngineering. – Kayaman Sep 16 '19 at 12:49
  • I don't have any problem in my code, just need some pointers, I don't think SO will be happy about giving them... – dgan Sep 16 '19 at 12:50
  • What do you mean by "When I receive my object from Database, I am sure to have a non-nullable version"? Do you mean immutable, because I doubt you'll always be using NOT NULL columns in the db. – Kayaman Sep 17 '19 at 6:18
1

Since you can model your data in multiple ways, you might get more than 2 classes out of this. You have the persistent state with its invariants, but that doesn't mean there's a single way to represent the data.

This is where Data Transfer Objects or DTOs come in play. I present to you some potential ways to view your AnObjectDBRow (or multiples of them):

public class NameValueDTO {
    String nameAndValue;  // Contains name + " " + value
}

public class ValuesForNameDTO {
    String name;
    Set<String> values;   // All values for given name
}

So does this mean you need to write more classes? Yes. It also documents your code when using proper naming and comments, as well as allowing stricter typing than having classes where things "can be null depending on how we're using it".

As DTOs are light-weight classes, there's not that much to maintain. A lot of the copying of values can be handled with automatic mappers (like Dozer).

It's your choice, do you want fewer classes or a more robust codebase?

Let's use a more realistic example:

public class UserEntity {
    String username;
    String firstname;
    String lastname;
    byte[] hash;
    String location;   // Could be null
}

public class UserDTO {
    String firstname;
    String lastname;
    String location;
}

Here we've left hash and username out of the DTO. We use them to authenticate, but this DTO is designed for human readable data so the result is a nicely encapsulated object. No usernames or password hashes here to confuse the people who use this class.

Of course the fact that location is null must be taken into account somehow, but that doesn't mean you need a class that doesn't have location attribute. Then you'd have to create 2 types of objects based on whether a field was null in the database, and that just wouldn't make sense.

  • Being just a singlestring, your NameValueDTO naturally decays to merely a string. You don't need the class, in other words. – Robert Harvey Sep 16 '19 at 13:11
  • @RobertHarvey except there's a whole lot of difference between passing String and passing NameAndValueDTO. A simplified example sure, but it does contain meta information in the classname, which makes it a little bit more than just a String. – Kayaman Sep 16 '19 at 13:18
  • Hmm I recognize the importance of a robust typing and codebase, but let's say I have N nullable fields for 1 object. Would I declare 2^N classes to represent possible combinations with only non-null fields?.. From Your answer, it follows, yes – dgan Sep 16 '19 at 13:48
  • @dgan of course not. You would design your DTO classes so they support your business logic. You don't create classes blindly based on whether a field is nullable or not. You may just have a DTO that's near-identical to your entity class, if there is nothing special about it. But they are on different layers of abstractions, so there is a significant difference between those classes. – Kayaman Sep 17 '19 at 6:17
  • @dgan edited to include a better example. – Kayaman Sep 17 '19 at 7:23

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.