Two constructors that do different things, but use the same data type

I recently ran into this problem with my class MorseString

. I have two different constructors that do different things but take the same data type:

/*
 * Constructor that takes the Morse Code as a String as a parameter
 */

public MorseString(String s) {
    if(!isValidMorse(s)) {
        throw new IllegalArgumentException("s is not a valid Morse Code");
    }
    // ...
}

      

and

/*
 * Constructor that takes the String as a parameter and converts it to Morse Code
 */

public MorseString(String s) {
    // ...
}

      

I came up with this solution:

public MorseString(String s, ParameterType type) {
    if(type == ParameterType.CODE) {
        if(!isValidMorse(s)) {
            throw new IllegalArgumentException("s is not a valid Morse Code");
        }
        // Constructor that takes Morse
    } else {
        // Constructor that takes String
    }
}

      

But it looks ugly. Any other solutions?

+3


source to share


2 answers


Since one of the constructors expects Morse code data to be ready (so it's more like a "constructor" - literally constructs an object from the data) and the other needs to do some conversion, it might make more sense to create a static factory method called convert

:

/*
 * Constructor that takes the Morse Code as a String as a parameter
 */

public MorseString(String s) {
    if(!isValidMorse(s)) {
        throw new IllegalArgumentException("s is not a valid Morse Code");
    }
    // ...
}

/*
 * Factory method that takes the String as a parameter and converts it to Morse Code
 */

public static MorseString convert(String s) {
    // ...
    return new MorseString(convertedString);
}

      



So, if you have a valid line of Morse code, you use the constructor to turn it into an object. However, if you have data that needs transformation, you call the static factory method:

MorseString ms = MorseString.convert(myString);

      

+4


source


Yes. Get rid of your constructors and use a different approach instead, like

1) A Factory Method , so you will have methods like this:

class MorseString {
    private MorseString(){};
    public static MorseString getFromCode(String s) {
        // ...
    }
    public static MorseString getFromString(String s) {
        // ...
    }
}

// Usage: MorseString.getFromCode(foo);

      

or



2) A Builder , so you will have methods like this

class MorseString {
    private MorseString(){};
    static class Builder {
       Builder initFromCode(String code) {
          // ..
          return this;
       }
       Builder initFromString(String str) {
          // ..
          return this;
       }
       MorseString build() {
          // ..
       }
    }
}

// Usage: MorseString.Builder.initFromCode(foo).build();

      

A constructor is good if you have very complex creation logic, many parameters, objects with some part of their information in the middle of creation, some preliminary checks, etc. A factory method is an easier approach for a situation where you have multiple ways to create an object with slightly varying parameters.

+9


source







All Articles