I've few common constants which are used by multiple classes.
What's the most effective way to design in this case:
Should I redefine the constants in each class?
Or should I separate such constants in a public class, and use the constants (in separate class) within each class?
Or is there any other better approach?
Note:- I'm looking for best OO technique which would be applicable for this.
Constants should be strictly related to some type, they shouldn't just "exist". A Constants class may seem convenient, but it will soon become unmaintainable, not to mention many consider it an antipattern.
It's hard to suggest improvements without seeing your code, but it seems like you need to rethink your design if you find yourself needing the same constants defined in a few different classes outside of the scope of a type.
Providing a Constant Util class is the cleanest way.
class ConstantUtil {
public static final int MAX_SIZE = 1<<10;
}
The typical folder heirarchy is like this
com.example.util.ConstantUtil
If the contants are dedicated to an api define them there. E.g.
public interface TaskService {
public static final int PRIORITY_LOW = -1;
public static final int PRIORITY_NORMAL = 0;
public static final int PRIORITY_HIGH = 1;
public void schedule(Task task, int priority);
}
If constants are not releated to a single api define a constants interface. E.g. javax.swing.WindowConstants.
Or is there any other better approach? Note:- I'm looking for best OO technique which would be applicable for this.
java
This brings us back to the question how constants are used. Most times they are used to write conditional code. E.g.
public class TaskServiceImpl implements TaskService {
private List<Task> lowPriority = new ArrayList<Task>();
private List<Task> normalPriority = new ArrayList<Task>();
private List<Task> highPriority = new ArrayList<Task>();
public void schedule(Task task, int priority){
if(priority == PRIORITY_HIGH ){
highPriority.add(task);
} else if(priority == PRIORITY_LOW ){
lowPriority.add(task);
} else if(priority == PRIORITY_NORMAL){
normalPriority.add(task);
} else {
....
}
}
}
In this case find out what the purpose of the constants is. In the example above the purpose is to group the tasks or if you think further to order them for execution. Move that logic to an own class. E.g. Introduce a Priority class that might implement Compareable ;)
You can also take a look at my blog about type-switches https://www.link-intersystems.com/blog/2015/12/03/enums-as-type-discriminator-anti-pattern/.
It is about enum misuse, but it also applies to constants.
You can try to create a class which contains all the constants(i.e, the second approach).
For example:
classname : MyConstantsClass.java
public static final String SOME_CONSTANT="value";
and then use it like
MyConstantsClass.SOME_CONSTANT
As some have suggested to use interface to create constants then I don't think that it would be a good choice. As using interface to create constants have certain disadvantages as well:
The usage of an interface does not allow to implement a mechanism for converting the constants to a visible/human readable
representation.
If the constants are an "implementation detail", an interface might not be the natural place for the value (CodeSmells, ListenToTheCode).
Due to Java compiler optimization, complete code recompilation of all classes using the constants is necessary if a constant changes.
Just changing the interface and recompiling it does not work (this
is, however the case with all constants defined as 'static final')
Please refer:
Interfaces For Defining Constants
Interface for constants
Class for constants
Constant class :
interface Constants {
int CONSTANT_ONE = 0;
int CONSTANT_TWO = 1;
int CONSTANT_THREE = 2;
String BASE_PATH = "YourPath";
}
And usage:
if (someValue == Constants.CONSTANT_ONE) {
}
Edit:
In most cases use interface instead of class if there is no need to implement this interface by some class, then it is no need to add this public static final, because by default it is public static final so your code looks more clean.
Design a class like AppUtil.java and and define your constants public static final like below:
public class AppUtil
{
public static final String IMAGE_STATUS="0";
}
and when you want to use variable use . like below:
AppUtil.IMAGE_STATUS
Related
I know there are several similar topics with similar title but I have actually slightly different questions than other topics.
I have designed such a solution which abstract class implements and interface, and in the constructor it calls default method of interface to initialize a map.
Here is my interface:
public interface ICalculator{
int VALUE_OF_X= 10;
int VALUE_OF_Y= 50;
int VALUE_OF_Z = 70;
Map<String, Integer> CHAR_VAL_MAP = new HashMap<String, Integer>(7);
default void initValueMap(){
CHAR_VAL_MAP.put("X", VALUE_OF_X);
CHAR_VAL_MAP.put("Y", VALUE_OF_Y);
CHAR_VAL_MAP.put("Z", VALUE_OF_Z);
}
public int calculate(final String inStr);
}
And created an abstract class:
public abstract class AbstractCalculator implements ICalculator{
protected AbstractCalculator(){
initValueMap();
}
}
My idea was here to ensure that initValueMap method is called implicitly by the abstract class.
And the concreate class which extend abstract class is:
public class MyCalculator extends AbstractCalculator{
public int calculate(final String romanNumberStr){
// some logic code
}
}
I have basically two question:
1) Is there any design problem or wrong usage of OOP concepts ?
2) In C++. using const for the parameter is good programming behaviour. But in java word, it is not so common. Is it bad to use final in method parameters?
You are over complicating things. Java 9 added some nice of() methods to the Collections utility class. You can use those to create a map filled with values without the need to call an extra init method. Then you pass that map instance to new HashMap() to get that data into a modifiable map instance. And with older java, you can always write a method that creates and returns a prefilled map. There is no need to do creation and filling like you do (in separate pieces of code).
For the record: you understand that all fields of an interface are static by default and thus shared between all code using them?!
Regarding final, there are quite some differences to const from C++. The only thing that a final parameter gives you is checking that prevents you from inadvertently writing to a parameter. It can be useful to have that, but most people simply don't use it because they add such little gain, but make code quite harder to read.
There are a few ways to ensure that calculate is only called after the map is fully initialized. One way is to declare and initialize it in the interface directly:
public interface ICalculator {
int VALUE_OF_X = 10;
int VALUE_OF_Y = 50;
int VALUE_OF_Z = 70;
Map<String, Integer> CHAR_VAL_MAP = initValueMap();
static Map<String, Integer> initValueMap() {
Map<String, Integer> map = new HashMap<String, Integer>(7);
map.put("X", VALUE_OF_X);
map.put("Y", VALUE_OF_Y);
map.put("Z", VALUE_OF_Z);
return map;
}
public int calculate(final String inStr);
}
This may be preferred because static data is being initialized statically, where it is declared (though most of us don't particularly like stuffing interfaces with this kind of code).
If you want to call this initialization code in the abstract class, you can still use a static block:
public abstract class AbstractCalculator implements ICalculator {
static {
ICalculator.initValueMap();
}
}
But the simplest is perhaps to go with Map.of as suggested in GhostCat's answer, unless your Java runtime is older than 9.
I am in a situation where I have an enum which has grown huge and gotten out of control on maintenance. I wanted to delegate responsibility to each class. However, there are certain common ones which qualifies as required in more than one class. I was thinking of defining a parent enum with necessary common ones defined and then extend parent enum by respective class's enums to add class specific entry. Java does not support extending enum. Does anyone know an better alternative?
I appreciate any suggestions provided. Thanks!
You should maybe switch to integers, like lots of JavaSE APIs do.
class Constants
{
public static final int COMMON_CONSTANT_1 = 1;
public static final int COMMON_CONSTANT_2 = 2;
....
static final int END_OF_COMMON_CONSTANTS = 127;
}
class AClass
{
public static final int CONSTANT_NEEDED_BY_ACLASS =
Constants.END_OF_COMMON_CONSTANTS + 1;
public static final int ANOTHER_CONSTANT =
CONSTANT_NEEDED_BY_ACLASS + 1;
....
}
This way any class can use the common constants and extend them with custom ones, without interfering with each other.
If your enumeration has only one property , you can move around in a file.properties , otherwise you may create inner enum class in a class to have everything neater
I have a lot of lines with common code, only 1 line in between differs for some implementations.
Normally I'd chose a strategy pattern for this. But I wonder if a enum switch() could be a better approach here. Take the following example. Assume the Object can be any object that has mathematical methods like add(), multiply(), substract() etc.
With enums I'd go like this:
enum Strategy {
ADD, SUB, MUL;
}
class DigitUtil {
public static void update(Object obj, int n, Strategy strat) {
//some DB stuff
switch(strat) {
case ADD: obj.add(n);
break;
case SUB: obj.subtract(n);
break;
case MUL: obj.multiply(n);
break;
}
//some other DB stuff
}
}
Usage:
DigitUtil.update(obj, 1, Strategy.ADD); //this adds 1 to the object
DigitUtil.update(obj, 10, Strategy.SUB); //this subtracts 10 from the object
Or would you rather pick the strategy pattern for those type of operations?
class DigitUtil {
public static void update(Object obj, int number, Strategy strat) {
//some DB stuff
strat.update(obj, number);
//some other DB stuff
}
interface Strategy {
void update(Object object, int number);
}
static class Add implements Strategy {
#Override
public oid update(Object obj, int n) {
obj.add(n);
}
}
static class Subtract implements Strategy {
#Override
public oid update(Object obj, int n) {
obj.subtract(n);
}
}
static class Multiply implements Strategy {
#Override
public oid update(Object obj, int n) {
obj.multiply(n);
}
}
public static final Strategy ADD = new DigitUtil.Add();
public static final Strategy SUB = new DigitUtil.Subtract();
public static final Strategy MUL = new DigitUtil.Multiply();
}
Usage:
DigitUtil.update(obj, 1, DigitUtil.ADD);
DigitUtil.update(obj, 10, DigitUtil.SUB);
Is there any benefit for one approach over the other? Which would you chose in which situation?
The strategy pattern (which would be much more concise if Java had lambdas already) is open to extension by additional strategies while the enum approach is not. As a design decision this essentially comes down to the expression problem.
Choose the enum approach if you have many methods that operate on those enums in different ways, and you perhaps want a compiler warning if you add an enum entry and forget to update one of those methods. Prefer the strategy pattern if you expect to define more operations, perhaps in other modules of the program.
If you only have one method processing the enums/strategies and the set of enums/strategies is unlikely to change then it doesn't matter which you choose. I'd probably go with enums in Java 7 because they are more concise.
Also, remember that enums can have methods, so the enum entries can implement your update method just like the strategies do. Whether to prefer this over a switch statement is a matter of taste.
This question can start a whole debate. Even if the first approach looks cleaner, I would go for the second approach - I mean the strategy pattern. Using the enums and switches make your code tight coupled - if new operations need to be added then the switch needs more cases. On the other hand, following OOAD and OOP best practices DRY and using the O from from SOLID(Open/Closed Principle that is) I would go for the Strategy pattern even if this code snippet it looks more complex.
Hope this helps you!
I think using enum would be a better approach.
It will force the programmer to use only one of those methods for
mathematical operations.
Personally, using enums looks cleaner to me than creating static classes for the same purpose.
If it is neededed to add or remove some mathematical operation, then its easier to modify an enum instead of making a static nested class implement an interface and then again instantiating it.
Again this is my personal opinion and it may differ from others
Suppose that you have created an SDK include the DigitUtil. Now one of thousand clients need to use this method with a new custom strategy (e.g Division):
In the enum approach, you must upgrade your SDK but using Strategy pattern you do not need to any change.
This question has been bothering me forever. I can wait to hear the responses. I see this too often
public interface Istuff
{
public static final int STATE_B = 4;
public static final int STATE_L = 5;
public static final int STATE_U = 6;
}
and also this one
public class MyStuffConstants
{
public static final String STATUS = "STATUS";
public static final String RUNNING = "RUNNING";
}
I would say Enum. as their sole purpose is to represent fixed set of constants.
Simple Example:
enum Season { WINTER, SPRING, SUMMER, FALL }
You should use enum for that. It's too powerful not to use it.
Don't use interfaces for that. It gets very messy as soon as you have many interfaces (which may come from interfaces extending other interfaces) : you need then to precise in what interfaces to pick the constants which nullifies the benefits of defining the constants in an interface.
The clean solution is to have a non instanciable class for that. Of course, when an enumeration is applicable (that is, the values are different possible values in the same semantic field), you should use an enum. But don't use an enum for this kind of constant :
public final static int DEFAULT_WIDTH = 666;
If you can also associate arbitrary data with your enum constants by adding a constructor:
public enum Season {
WINTER(1, 15), SPRING(2, 92), SUMMER(3, 40), FALL(50, 9);
private final int foo;
private final int bar;
Season(int foo, int bar) {
this.foo = foo;
this.bar = bar;
}
public int getFoo() {
return foo;
}
public int getBar() {
return bar;
}
}
For the IStuff example I think enums is kind of awkward if you don't actually need the whole exclusive ordering bit - you'll end up basically creating a class for wrapping an integer.
The MyStuffs example makes sense to make an enum out of, as long as the name of the constant works for you.
It comes down to who will be using the constants - sometimes it makes sense to use constants internally in a class (avoiding magic values). In that case "private static final * *;" works fine.
If you want the constants to be useful as part of an API then sure do constants as in iStuff (btw you can lose the "public static final" bit, which is default when putting them like that in an interface).
Edit: and if you don't have an interface to begin with, and you have constants that clearly belong to a specific, even though the constants need to be public, I don't see the need to create a separate interface just to have somewhere to put the constants. If however the constants will be used in two or more classes/apis and belong in one place more than another, then sure why not put the constants in a separate interface.
I think the concept of constants is too complex to be answered by a general "do this" statement.
Motivation
Recently I searched for a way to initialize a complex object without passing a lot of parameter to the constructor. I tried it with the builder pattern, but I don't like the fact, that I'm not able to check at compile time if I really set all needed values.
Traditional builder pattern
When I use the builder pattern to create my Complex object, the creation is more "typesafe", because it's easier to see what an argument is used for:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
...
.build();
But now I have the problem, that I can easily miss an important parameter. I can check for it inside the build() method, but that is only at runtime. At compile time there is nothing that warns me, if I missed something.
Enhanced builder pattern
Now my idea was to create a builder, that "reminds" me if I missed a needed parameter. My first try looks like this:
public class Complex {
private String m_first;
private String m_second;
private String m_third;
private Complex() {}
public static class ComplexBuilder {
private Complex m_complex;
public ComplexBuilder() {
m_complex = new Complex();
}
public Builder2 setFirst( String first ) {
m_complex.m_first = first;
return new Builder2();
}
public class Builder2 {
private Builder2() {}
Builder3 setSecond( String second ) {
m_complex.m_second = second;
return new Builder3();
}
}
public class Builder3 {
private Builder3() {}
Builder4 setThird( String third ) {
m_complex.m_third = third;
return new Builder4();
}
}
public class Builder4 {
private Builder4() {}
Complex build() {
return m_complex;
}
}
}
}
As you can see, each setter of the builder class returns a different internal builder class. Each internal builder class provides exactly one setter method and the last one provides only a build() method.
Now the construction of an object again looks like this:
new ComplexBuilder()
.setFirst( "first" )
.setSecond( "second" )
.setThird( "third" )
.build();
...but there is no way to forget a needed parameter. The compiler wouldn't accept it.
Optional parameters
If I had optional parameters, I would use the last internal builder class Builder4 to set them like a "traditional" builder does, returning itself.
Questions
Is this a well known pattern? Does it have a special name?
Do you see any pitfalls?
Do you have any ideas to improve the implementation - in the sense of fewer lines of code?
The traditional builder pattern already handles this: simply take the mandatory parameters in the constructor. Of course, nothing prevents a caller from passing null, but neither does your method.
The big problem I see with your method is that you either have a combinatorical explosion of classes with the number of mandatory parameters, or force the user to set the parameters in one particular sqeuence, which is annoying.
Also, it is a lot of additional work.
public class Complex {
private final String first;
private final String second;
private final String third;
public static class False {}
public static class True {}
public static class Builder<Has1,Has2,Has3> {
private String first;
private String second;
private String third;
private Builder() {}
public static Builder<False,False,False> create() {
return new Builder<>();
}
public Builder<True,Has2,Has3> setFirst(String first) {
this.first = first;
return (Builder<True,Has2,Has3>)this;
}
public Builder<Has1,True,Has3> setSecond(String second) {
this.second = second;
return (Builder<Has1,True,Has3>)this;
}
public Builder<Has1,Has2,True> setThird(String third) {
this.third = third;
return (Builder<Has1,Has2,True>)this;
}
}
public Complex(Builder<True,True,True> builder) {
first = builder.first;
second = builder.second;
third = builder.third;
}
public static void test() {
// Compile Error!
Complex c1 = new Complex(Complex.Builder.create().setFirst("1").setSecond("2"));
// Compile Error!
Complex c2 = new Complex(Complex.Builder.create().setFirst("1").setThird("3"));
// Works!, all params supplied.
Complex c3 = new Complex(Complex.Builder.create().setFirst("1").setSecond("2").setThird("3"));
}
}
No, it's not new. What you're actually doing there is creating a sort of a DSL by extending the standard builder pattern to support branches which is among other things an excellent way to make sure the builder doesn't produce a set of conflicting settings to the actual object.
Personally I think this is a great extension to builder pattern and you can do all sorts of interesting things with it, for example at work we have DSL builders for some of our data integrity tests which allow us to do things like assertMachine().usesElectricity().and().makesGrindingNoises().whenTurnedOn();. OK, maybe not the best possible example but I think you get the point.
Why don't you put "needed" parameters in the builders constructor?
public class Complex
{
....
public static class ComplexBuilder
{
// Required parameters
private final int required;
// Optional parameters
private int optional = 0;
public ComplexBuilder( int required )
{
this.required = required;
}
public Builder setOptional(int optional)
{
this.optional = optional;
}
}
...
}
This pattern is outlined in Effective Java.
Instead of using multiple classes I would just use one class and multiple interfaces. It enforces your syntax without requiring as much typing. It also allows you to see all related code close together which makes it easier to understand what is going on with your code at a larger level.
IMHO, this seems bloated. If you have to have all the parameters, pass them in the constructor.
I've seen/used this:
new ComplexBuilder(requiredvarA, requiedVarB).optional(foo).optional(bar).build();
Then pass these to your object that requires them.
The Builder Pattern is generally used when you have a lot of optional parameters. If you find you need many required parameters, consider these options first:
Your class might be doing too much. Double check that it doesn't violate Single Responsibility Principle. Ask yourself why you need a class with so many required instance variables.
You constructor might be doing too much. The job of a constructor is to construct. (They didn't get very creative when they named it ;D ) Just like classes, methods have a Single Responsibility Principle. If your constructor is doing more than just field assignment, you need a good reason to justify that. You might find you need a Factory Method rather than a Builder.
Your parameters might be doing too little. Ask yourself if your parameters can be grouped into a small struct (or struct-like object in the case of Java). Don't be afraid to make small classes. If you do find you need to make a struct or small class, don't forget to refactor out functionality that belongs in the struct rather than your larger class.
For more information on when to use the Builder Pattern and its advantages you should check out my post for another similar question here
Question 1: Regarding the name of the pattern, I like the name "Step Builder":
http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html
http://www.javacodegeeks.com/2013/05/building-smart-builders.html
Question 2/3: Regarding pitfalls and recommendations, this feels over complicated for most situations.
You are enforcing a sequence in how you use your builder which is unusual in my experience. I could see how this would be important in some cases but I've never needed it. For example, I don't see the need to force a sequence here:
Person.builder().firstName("John").lastName("Doe").build()
Person.builder().lastName("Doe").firstName("John").build()
However, many times the builder needed to enforce some constraints to prevent bogus objects from being built. Maybe you want to ensure that all required fields are provided or that combinations of fields are valid. I'm guessing this is the real reason you want to introduce sequencing into the building.
In this case, I like recommendation of Joshua Bloch to do the validation in the build() method. This helps with cross field validation because everything is available at this point. See this answer: https://softwareengineering.stackexchange.com/a/241320
In summary, I wouldn't add any complication to the code just because you are worried about "missing" a call to a builder method. In practice, this is easily caught with a test case. Maybe start with a vanilla Builder and then introduce this if you keep getting bitten by missing method calls.