Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inject property values into enum?

Tags:

java

enums

spring

I'm using Spring to resolve property values from properties file, usually with @Value("${my.property}").

Now I have an enum that should have an application-wide configurable static number. For example:

public enum PersonType {
    ADULT, CHILD;
    private static final int MAX_CHILD = 17;

    public static PersonType fromAge(int age) {
        return age <= MAX_CHILD ? CHILD : ADULT;
    }
}

How could I make the max child age configurable and injectable by Spring?

like image 683
membersound Avatar asked Jul 04 '14 09:07

membersound


1 Answers

It's an interesting question, how one handles variables that is the same for all objects of the class and does not change during runtime, and at the same time is allowed to be configurable between executions. Since the first two prerequisites dictate that the variable should be static and final (e.g. a constant), the third really doesn't fit in, meaning that there will be no pretty way to achieve all three (reflection is needed, or one has to drop either the static or the final constraint).

Since there is no pretty solution to the way things are modeled now, I think the wisest would be to take a step back and rethink the placement of the variable: Is it necessary to keep this logic in the enum itself? What is different when changing the value of the constant, the enum itself, or something else? In what cases does this constant have to change it's value?

In your example it might be that different countries have different thresholds for what is regarded as adult, or that the threshold changes, then maybe a small service that determines which PersonType a Person has is the right way to go.

@Service
public class PersonTypeService {
    @Value("${threshold.for.adulthood}")
    private int thresholdForAdulthood;

    public PersonType determinePersonType(final Person person) {
        if (person.getAge() >= thresholdForAdulthood) {
            return PersonType.ADULT;
        }
        return PersonType.CHILD;
    }  
}

In general I like to let enums only answer the "what", and leave the "how" and the "why" to domain classes and services. In the example, all the enum needs to know is the values it provides a person, why it should provide a certain value, or how it is determined, does not belong in the enum.

like image 72
Tobb Avatar answered Oct 16 '22 16:10

Tobb