I have recently ran into this problem with my MorseString
class. 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?
Yes. Get rid of your constructors and use instead some other approach, such as
1) A Factory Method , so you'd 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'd 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 builder is good if you have a highly complex creation logic, lots of parameters, having objects with only some of their information in mid-creation, some preliminary validations etc. A factory method is lighter approach for a situation where you have multiple ways of creating your object with slightly varying parameters.
Since one of the constructors is expecting ready-made Morse Code data (so it is more like a "constructor" - literally constructing an object from the data), and the other has to do some conversion, it might make more sense to make a static factory method called something like 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 had a valid morse code string, you use the constructor to turn it into an object. However if you have data that needs conversion, you would call the static factory method:
MorseString ms = MorseString.convert(myString);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.