Reputation: 164
I have entity in database, say, MonthPlan:
class MonthPlan {
private boolean approved;
// other fields
}
There is also REST interface, which accepts external requests based on which program changes entity instances. For example, request
class EditMonthPlanRequest {
private long amount;
// other fields
}
is used to change month plan amount.
What I need is to execute different actions on MonthPlan
entity based on value of approved
field. For example, code for mentioned request could be as following
MonthPlan plan = getPlan(...);
if (plan.isApproved()) {
// actions using data from EditMonthPlanRequest
} else {
// other actions using data from EditMonthPlanRequest
}
There would be 5-6 different requests each with exactly two variants of actions based on value of approved
field of edited entity. What OOP design pattern can I use for such use case to write more concise code?
Upvotes: 1
Views: 2017
Reputation: 1422
In this scenario, the state pattern is more suitable.
State design pattern is used when an Object changes its behavior based on its internal state.
If we have to change behavior of an object based on its state, we can have a state variable in the Object and use if-else condition block to perform different actions based on the state. State pattern is used to provide a systematic and lose-coupled way to achieve this through Context and State implementations.
Try to implement based on your description:
public class StatePattern {
public static void main(String[] args) {
MonthPlan monthPlan = null; //= new MonthPlan(...)
StateContext stateContext = new StateContext();
if(monthPlan.isApproved()) {
stateContext.setState(new Approved());
}else {
stateContext.setState(new NotApproved());
}
}
}
class MonthPlan {
private boolean approved;
public boolean isApproved() {
return approved;
}
// other fields
}
interface State{
public void doAction(StateContext ctx);
}
class StateContext{
private State currentState;
public StateContext() {
//default Approved state, you can change if you want
currentState = new Approved();
}
public void setState(State state) {
currentState = state;
}
public void doAction() {
currentState.doAction(this);
}
}
class Approved implements State{
@Override
public void doAction(StateContext ctx) {
//actions using data from EditMonthPlanRequest
}
}
class NotApproved implements State{
@Override
public void doAction(StateContext ctx) {
//other actions using data from EditMonthPlanRequest
}
}
Upvotes: 1
Reputation: 17066
If you want to do OOP, then replace conditionals with polymorphism.
In this example, it means splitting MonthPlan
in two.
class ApprovedMonthPlan extends MonthPlan
class UnapprovedMonthPlan extends MonthPlan
Each class handles EditMonthPlanRequest
in its own way.
Upvotes: 0
Reputation: 17846
For this simple case, the Template Method pattern may apply:
abstract class AbstractRequest {
public void execute(...){
MonthPlan plan = getPlan(...);
if (plan.isApproved()) {
executeForApproved(plan);
} else {
executeForNonApproved(plan);
}
}
protected abstract void executeForApproved(MonthPlan plan);
protected abstract void executeForNonApproved(MonthPlan plan);
}
This way, you don't need to repeat the if statement and the getPlan(...) in each subclass:
class EditMonthPlanRequest extends AbstractRequest {
private long amount;
// other fields
protected void executeForApproved(MonthPlan plan){
...
}
protected void executeForNonApproved(MonthPlan plan){
...
}
}
Upvotes: 0
Reputation: 6255
I do not think you need a design pattern in such a simple case. Each request will be processed by the corresponding method at Service layer.
Upvotes: 2