Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

According to DDD-principles I use factory-methods to create consistent objects and to ensure that the objects are in the right state.

Now I'm in doubt about inner logic of setter methods. I'm tied up with an object, that's similar to the following code snippet, so let's take it as an example:

public class UserCredentials {

    private String username;

    private UserCredentials() {
        super();
    }

    public static UserCredentials create (final String username) {
        String username = username.toUpperCase();
        UserCredentials newInstance = new UserCredentials(username);
        return newInstance;
    }

    private UserCredentials(final String username) {
        this.username = username;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public void checkConsitency() {
        ...
        isUppercase();
        ...
    }
}

We do have an invariant: The username of the credentials must always be uppercase. Now I want to make sure, that changing the username doesn't violate the invariant.

But how do I guarantee the rule?

  1. I do rewrite the setter method and add the conversion logic to the setter. Drawback: Setter contains logic.

  2. I rely on clients, that they always provide uppercase username and I will throw consistency exceptions in the case of violation. Drawback: Origin of the wrong usage is hard to discover, moreover its bad practice at all.

  3. I remove the setter method and replace it with a domain method like changeUsername(String username) that contains the conversion logic. Drawback: external developers may miss the setter method.

Because of the statement "username of credential must always be uppercase" I tend to prefer alternative 3.

But is there a smarter solution?

share|improve this question
1  
What's the point of a setter that doesn't have any logic? Make it public then. –  Mahdi Apr 8 '14 at 9:42

1 Answer 1

Choose solution #1. There is nothing wrong with setters containing validation or coercion logic. In fact, that is the only reason why we'd use setters and getters instead of public member fields!

Your create factory method is also a bit awkward, as there is no reason not to use the constructor instead:

public class UserCredentials {

    private String username;

    public UserCredentials(final String username) {
        super();
        this.username = coerceUsername(username);
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(final String username) {
        this.username = coerceUsername(username);
    }

    private static String coerceUsername(final String username) {
        return username.toUpperCase();
    }
}
share|improve this answer
    
It's bad practice to use logic in constructors that can throw exceptions. Especially the example can throw NPE, if username is null. Not really smart. –  shylynx Apr 8 '14 at 9:47
    
@shylynx good point, but sometimes throwing exceptions is the best thing to do, even in constructors – constructing an object in an illegal state is a worse problem. If you really want to avoid this, you need the builder pattern. –  amon Apr 8 '14 at 9:49
    
@shylynx Not a problem if null is forbidden. –  Doval Apr 8 '14 at 11:55

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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