I would like to implement the state pattern in java for the following scenario:
The whole story is persisted with EclipseLink
A Person
has a SecurityState
(= Security Level).
Depending on a persons previous SecurityState
, an operation changeSecurityLevel
(and probably other operations too) will have different behaviour.
Person Class
@Entity
public class Person extends DatabaseObject{
// .... lots of properties....
@ManyToOne(fetch=FetchType.LAZY)
private SecurityState securityState;
public changeSecurityState(SecurityState newState){
securityState.changeSecurityState(newState);
}
}
SecurityState:
@Entity
public abstract class SecurityState extends DatabaseObject{
private int level; // 1 = low, 2 = medium, 3 = high
private Person person;
public SecurityState(Person p){
this.person = p;
}
public changeSecurityState(SecurityState newState){
// not implemented
}
public void someOtherOperation(){
}
// getter and setter
}
For example the HighSecurityState
:
@Entity
public class HighSecurityState extends SecurityState {
private int level = 3;
public changeSecurityState(SecurityState newState){
if(newState.getLevel() == 1){
// do specific stuff for High-to-Low status changes
person.securityState = new LowSecurityState();
}else if(newState.getLevel() == 2){
person.securityState = new MediumSecurityState();
}else{ }
}
}
Questions: - Is the state-pattern more or less correctly implemented? I don't like the if-else somehow, this doesn't really feel right.
SecurityState
? Or the concrete state classes?Don't worry about if-else
for such simple cases; it's fine.
Maybe switch
looks a little better - but it's essentially the same thing
switch(newState.getLevel())
case 1:
...
case ...
default: throw new AssertionError();
Or you could even go apply Visitor pattern - is it really worth it though?
public changeSecurityState(LowSecurityState newState)
...
public changeSecurityState(MediumSecurityState newState)
...
public changeSecurityState(HighSecurityState newState)
...
On the 2nd question - security state is just a simple int; you don't need a separate table for it; it should just be an integer column in the person table. You can make it an enum
type in Java if you like.
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.