Since Java 1.4 doesn't have enums I'm am doing something like this:
public class SomeClass {
public static int SOME_VALUE_1 = 0;
public static int SOME_VALUE_2 = 1;
public static int SOME_VALUE_3 = 2;
public void receiveSomeValue(int someValue) {
// do something
}
}
The caller of receiveSomeValue should pass one those 3 values but he can pass any other int.
If it were an enum the caller could only pass one valid value.
Should receiveSomeValue throw an InvalidValueException?
What are good alternatives to Java 5 enums?
Best to use in pre 1.5 is the Typesafe Enum Pattern best described in the book Effective Java by Josh Bloch. However it has some limitations, especially when you are dealing with different classloaders, serialization and so on.
You can also have a look at the Apache Commons Lang project and espacially the enum class, like John has written. It is an implementation of this pattern and supports building your own enums.
I'd typically create what I call a constant class, some thing like this:
public class MyConstant
{
public static final MyConstant SOME_VALUE = new MyConstant(1);
public static final MyConstant SOME_OTHER_VALUE = new MyConstant(2);
...
private final int id;
private MyConstant(int id)
{
this.id = id;
}
public boolean equal(Object object)
{
...
}
public int hashCode()
{
...
}
}
where equals and hashCode are using the id.
Apache Commons Lang has an Enum class that works well and pretty well covers what Java 5 Enums offer.
If the application code base is going to use lot of enums, then I would prefer following solution, which I have used in my application.
Base Class
public class Enum {
protected int _enumValue;
protected Enum(int enumValue) {
this._enumValue = enumValue;
}
public int Value() {
return this._enumValue;
}
}
Your enumerations will then follow these pattern
Actual Enum
public class DATE_FORMAT extends Enum {
public static final int DDMMYYYY = 1;
public static final int MMDDYYYY = 2;
public static final int YYYYMMDD = 3;
public DATE_FORMAT(int enumValue) {
super(enumValue);
}
}
And your code can consume this enum as follows
String getFormattedDate(DATE_FORMAT format) {
String sDateFormatted = "";
switch (format.Value()) {
case DATE_FORMAT.DDMMYYYY :
break;
case DATE_FORMAT.MMDDYYYY :
break;
case DATE_FORMAT.YYYYMMDD :
break;
default:
break;
}
return sDateFormatted;
}
Caller can use the function as
void callerAPI() {
DATE_FORMAT format = new DATE_FORMAT(DATE_FORMAT.DDMMYYYY);
String sFormattedDate = getFormattedDate(format);
}
This is yet not full proof against intitializing derived Enum objects with any integer value. However it can provide good syntactic guideline to work in non-enum environment.
Related
I have the following java code:
...
public final class Constants {
...
public static class Languages {
...
public static class en_US {
public static final String VALIDATION_REGEX = "[a-zA-Z-' ]+";
...
}
public static class en_GB {
public static final String VALIDATION_REGEX = "[a-zA-Z-' ]+";
...
}
}
...
}
My problem is as follows:
I receive a text and a language, and I have to check, whether that text is written only with valid alphabetic characters of that given language.
My code so far is as follows:
...
public boolean isContentValid(String content, String language) {
Boolean isCorrect = false;
switch (language) {
...
case "en_US":
isCorrect = content.matches(Constants.Phrases.en_US.VALIDATION_REGEX);
break;
case "en_GB":
isCorrect = content.matches(Constants.Phrases.en_GB.VALIDATION_REGEX);
break;
...
default:
isCorrect = false;
}
return isCorrect;
}
...
This is fine and works, but as I add languages to my application, I will have to add more and more cases to my switch.
And I was wondering if in Java there is a way to dynamically name a static nested class, something like:
Constants.Phrases[language].VALIDATION_REGEX
So my above code could be something like:
...
public boolean isContentValid(String content, String language) {
return content.matches(Constants.Phrases[language].VALIDATION_REGEX);
}
...
Thank you, and sorry if this is something super easy.
I am a JavaScript developer, and just learning Java.
Looking at you use case maybe this is a better approach:
public enum Language {
en_US("engUS_reg"),
en_GB("engGB_reg");
private final String regex;
Language(String regex) {
this.regex = regex;
}
public String getRegex() {
return regex;
}
}
And using this enum class write your method as follows:
public boolean isContentValid(String content, String language) {
return content.matches(Language.valueOf(language).getRegex());
}
You could use an enum for something like this.
"An enum can, just like a class, have attributes and methods. The only difference is that enum constants are public, static and final (unchangeable - cannot be overridden)." - [w3][1]
public enum Languages {
EN_US {
#Override
public String toString() {
return "[a-zA-Z-' ]+";
}
},
EN_GB {
#Override
public String toString() {
return "[a-zA-Z-' ]+";
}
},
}
And then you can access these values like this
Languages.valueOf("EN_US");
As mentioned by #Pshemo you could avoid a class based approach entirely and use an implementation of Map if you want something a little more lightweight
[1]: https://www.w3schools.com/java/java_enums.asp#:~:text=An%20enum%20can%2C%20just%20like,but%20it%20can%20implement%20interfaces).
I have made this four classes and I'm wondering if I used the template method design pattern correctly because I'm really struggeling with this subject.
I have used the methods getPrijsBehandeling() and getBeschrijvingBehandeling() as my abstract classes.
Also I'm wondering if I should use the abstract methods in my UML or only in the code.
Since this is the first time I'm using a design pattern I wonder if I’m on the right track.
public abstract class Behandeling {
private String beschrijving;
private double prijs;
private int behandelingsNummer;
private Wassen wassen;
public Behandeling(int behandelingsNummber, int keuze) {
this.behandelingsNummer = behandelingsNummber;
if(keuze == 3 || keuze == 4) {
wassen = new Wassen();
}
}
public abstract double getPrijsBehandeling();
public abstract String getBeschrijvingBehandeling();
public double getPrijs() {
prijs = getPrijsBehandeling();
if(wassen != null) {
prijs += wassen.getPrijsBehandeling();
}
return prijs;
}
public String getBeschrijving() {
beschrijving = getBeschrijvingBehandeling();
if(wassen != null) {
beschrijving += wassen.getBeschrijvingBehandeling();
}
return beschrijving;
}
public int getBehandelingsNummer() {
return behandelingsNummer;
}
}
------------------------------------------
public class Verven extends Behandeling {
public Verven(int behandelingsNummer, int keuze) {
super(behandelingsNummer, keuze);
}
#Override
public double getPrijsBehandeling() {
return 20;
}
#Override
public String getBeschrijvingBehandeling() {
return "Haren worden geverfd";
}
}
---------------------------------------------
public class Knippen extends Behandeling{
public Knippen(int behandelingsNummer, int keuze) {
super(behandelingsNummer, keuze);
}
#Override
public double getPrijsBehandeling() {
return 15;
}
#Override
public String getBeschrijvingBehandeling() {
return "Haren worden geknipt";
}
}
-----------------------------------------------------
public class Wassen {
private double prijs;
private String beschrijving;
public Wassen() {
this.prijs = 7.50;
this.beschrijving = " en haren worden gewassen";
}
public double getPrijsBehandeling() {
return prijs;
}
public String getBeschrijvingBehandeling() {
return beschrijving;
}
}
The methods (aka “operation”, in UML speak) geefPrijs()and geefBeschrijving() are indeed designed according to the template method pattern: the base class implements the general algorithm, encapsulating the “primitive” parts that may need to be specialized into separate methods that can be overridden (i.e. “specialized”, in UML speak) by class extensions.
If the base class cannot provide its own implementation of a “partial” methods, you would make it abstract. But although this is how the pattern is usually described, in practice this is not an obligation: it is perfectly valid that the base class provides a default behavior that is not always overridden. The UML diagram should reflect your design in this regard, if there are abstract elements.
Some additional hints
In your design getPrijs() (template method) and getPrijsBehandeling() (primitive used in the template method) are both public and have names that create a risk of confusion:
if the primitive is not intended to be used for other purposes, it is one of the rare situation where making it protected could be a good idea.
if you prefer to avoid protected, you could use a naming convention. GoF suggests the “do” prefix inspired from a framework that didn’t survive. I prefer “prepare” like preparePrijsBehandeling() and prepareBeschrijvingBheandeling() because it immediately raises the question “prepare for what?” preventing inappropriate use.
It’s not the case here, but of course, if the primitive is a primitive operation that makes sense outside of the template methods, then there is no issue (example: surface() or perimeter() or barycenter() that are geometric characteristics of a shape that may be relevant for some template methods but make sense on their own).
I have few constant values which I refer across my application. I am creating a class something like below snippet.
public class Styles {
public static final String tableStyle = "TableGrid";
public static final String fontFamily = "Calibri";
public static final String headerStyle = "Heading2";
public static final String footerStyle = "Heading3";
public static final String tableHeaderStyle = "Heading1";
public static final String tableDataFontFamily = "Cambria";
public static final int tableHeaderFontSize = 16;
public static final int tableDataFontSize = 12;
}
I am assigning the values in it and I am referring them like Styles.headerStyle . My doubt is, is this the good way or is there any better approach to achieve this? something like Enum ?
Thanks in advance.
It depends on the nature of your application, in most cases it is not a good practice to have a collection of constants in that way, but it is difficult to tell without knowing the context of your application. BTW, are sure that you'll never (or almost never) change things like "fontFamily"?
Of course an enum would be a little less verbose and more functional:
public enum Styles {
TABLE_STYLE("TableGrid"),
FONT_FAMILY("Calibri"),
HEADER_STYLE("Heading2"),
FOOTER_STYLE("Heading3"),
TABLE_HEADER_STYLE("Heading1"),
TABLE_DATA_FONT_FAMILY("Cambria"),
TABLE_HEADER_FONT_SIZE("16"),
TABLE_DATA_FONT_SIZE("12");
private String value;
private Styles(String value) {
this.value = value;
}
public String getStringValue() {
return value;
}
public int getIntValue() {
return Integer.valueOf(value);
}
}
1) You can use an external file as a Property File.
2) You can use an enum as #morgano answer
3) I would change your class declaration to
public final class Styles { // final class can't have childs
private Styles(){} // you cannot instanciate
public static final String tableStyle = "TableGrid";
.
.
.
}
I have a load of images of musical symbols which I need to do some processing on and for each one I need to get the integer code corresponding to its file name. There are 23 possible file name strings and 23 integer code and there are many images with the same name under different directories.
The solution I have so far is given (abbreviated) below. I have just defined a load of int and String constants and then written a method which is just a huge chain of if statements to do the translation.
What would be a better way to achieve the same effect? The way I've done it seems really awful! I thought about using some kind of Map, but I wasn't sure of the best way to do so.
public class Symbol {
public static final int TREBLE_CLEF = 0;
public static final int BASS_CLEF = 1;
public static final int SEMIBREVE = 2;
// ...
public static final String S_TREBLE_CLEF = "treble-clef";
public static final String S_BASS_CLEF = "bass-clef";
public static final String S_SEMIBREVE = "semibreve";
// ...
public static int stringCodeToIntCode(String strCode) {
if (strCode == S_TREBLE_CLEF) {
return TREBLE_CLEF;
} else if (strCode == S_BASS_CLEF) {
return BASS_CLEF;
} else if (strCode == S_SEMIBREVE) {
return SEMIBREVE;
} //...
else {
return -1;
}
}
}
I think you are looking for Enum where you can have String constant and its value.
Example:
public enum YourEnumClass{
STRING_CONST (5),
STRING_CONST2 (7),
.....
//constructor
//getValue() method
}
read linked tutorial for more details.
enum StringToInt{
TREBLE_CLEF(0),
......
}
Enum is the way to go.
Another example:
public enum Color {
WHITE(21), BLACK(22), RED(23), YELLOW(24), BLUE(25);
private int code;
private Color(int c) {
code = c;
}
public int getCode() {
return code;
}
how about a hashmap
HashMap<String,Integer> hm=new HashMap<String,Integer();
hm.put("treble-clef",0);
//rest
and get it by using this
int value=hm.get("treble-clef");
I have encountered a weird problem in my app (java).
I have an enum. Something like that
public enum myEnum implement myIntrface{
valueA(1),valueb(2),valuec(3),valued(4)
private int i;
// and then - a constructor
public MyEnum(int number){
i = number;
}
private MyObj obj = new MyObj;
// getter and setter for obj
}
and in another class I have this
MyEnum.valueA.setObj(new Obj(...))
in briefe - I have an enum with a private instance member that has a set and a get.
So far so good -
The only thing that amazes me is that later on I look at the value of the MyEnum.valueA().obj is null.
there is nothing that updates the value to null, I have even gave it a default value in the constructor and I still see it null later.
any suggestions?
Enums should be un-modifiable classes so you shouldn't really be doing this. If your looking to modify the state of a type based object like an enum you should use an final class approach with embedded constants. Below is an example of a class based approach with a modifiable name an a un-modifiable name...
public final class Connection {
public static final Connection EMAIL = new Connection("email");
public static final Connection PHONE = new Connection("phone");
public static final Connection FAX = new Connection("fax");
/**/
private final String unmodifiableName; //<-- it's final
private String modifiableName;
/*
* The constructor is private so no new connections can be created outside.
*/
private Connection(String name) {
this.unmodifiableName = name;
}
public String getUnmodifiableName() {
return unmodifiableName;
}
public String getModifiableName() {
return modifiableName;
}
public void setModifiableName(String modifiableName) {
this.modifiableName = modifiableName;
}
}
The purpose of enums is to represent constant values. It does not make any sense to set the fields of a constant value.
You should declare your fields as final, and use the constructor to initialize all of them.
For reference, the following code works as expected:
public class Test {
public static enum MyEnum {
valueA(1),valueb(2),valuec(3),valued(4);
private int i;
private Object o;
private MyEnum(int number) {
i = number;
}
public void set(Object o) {
this.o = o;
}
public Object get() {
return o;
}
}
public static void main(String[] args) {
System.out.println(MyEnum.valueA.get()); // prints "null"
MyEnum.valueA.set(new Integer(42));
System.out.println(MyEnum.valueA.get()); // prints "42"
}
}
the cause of this problem is the db40 framework . It loads an enum from the db using reflection. This is well documented .
http://developer.db4o.com/Forums/tabid/98/aft/5439/Default.aspx