Compare the state pattern and the policy pattern in Java design pattern programming
- 2020-05-09 18:39:19
- OfStack
In order to properly use the state and policy patterns in Java applications, developers need to be aware of the differences between the two. Although the structure of the state pattern and the policy pattern are very similar, they both follow the open and closed principle and represent the 'O' of the SOLID design principle, their intentions are completely different. The policy pattern in Java encapsulates a set of related algorithms, giving callers runtime flexibility. Callers can select a different algorithm at run time without modifying the Context class that USES the policy. Classic examples of using the policy pattern include implementing encryption algorithms, compression algorithms, and sorting algorithms. On the other hand, the state mode can use an object to show different behaviors in different states. Objects in the real world are stateful, and they will behave differently depending on the state. For example, a vending machine can only sell items in the hasCoin state. If you don't put COINS in it, it won't sell. Now you can clearly see the difference between the policy pattern and the state pattern, and their purposes are different. The state pattern helps the object manage its state, while the policy pattern allows the client to choose different behaviors. One less obvious difference is who drives behavior change. In the policy pattern, it is client-driven, which provides different policies for context information, while in the state pattern, the migration of states is managed by the Context or State objects themselves. Similarly, if you make state changes in the State object, it must hold a reference to Context, which means that for the vending machine, it can call the setState method to modify the current state of Context. On the other hand, the policy object does not hold a reference to Context; its client passes the selected policy to Context. The strategy mode and the state mode are the most common interview questions about the Java design pattern, which we will cover in detail in this article on the Java design pattern. We will explore the similarities and differences between the two models, which will help improve your understanding of them.
Similarities between the state mode and the policy mode:
If you look at the UML diagram for the policy pattern and the state pattern, they look very similar. In state mode, objects that use State objects to change behavior are called Context objects, and similarly in policy mode, objects that use Strategy objects to change behavior are also Context objects. Remember, the client interacts with the Context object. In the state mode, Context proxies method calls to the state object, the current object in Context is the concrete state object, and in the policy mode, Context operates on the policy object, which is either passed in as a parameter or provided when the Context object is created.
Let's look at some similarities between the two core Java design patterns:
Both the state pattern and the policy pattern make it easy to add new states or policies without affecting the Context objects that use them
Both patterns follow an open and closed design principle, which means that your design is open for extension and closed for modification. In both modes, Context is closed to modification, adding states or policies so that you don't need to modify Context objects in other states, or make minor changes
Just as Context objects in state mode have an initial state of 1, Context in policy mode usually has a default policy.
State patterns encapsulate different behaviors in the way of different state objects, while policy patterns encapsulate different behaviors in the way of different policy objects.
Both patterns rely on concrete subclasses to implement concrete behavior. Each concrete policy extends from an abstract policy class, and each state is an interface or subclass of an abstract class that represents the state.
State mode instance
public class WindowState {
private String stateValue;
public WindowState(String stateValue) {
this.stateValue = stateValue;
}
public String getStateValue() {
return stateValue;
}
public void setStateValue(String stateValue) {
this.stateValue = stateValue;
}
public void handle() {
/*
* You do different things in different states, Reswitch state
*/
if (" window ".equals(stateValue)) {
switchWindow();
this.stateValue = " Full screen ";
} else if (" Full screen ".equals(stateValue)) {
switchFullscreen();
this.stateValue = " window ";
}
}
private void switchWindow() {
System.out.println(" Switch to window state ");
}
private void switchFullscreen() {
System.out.println(" Switch to full screen ");
}
}
/**
* Use of state
*/
public class WindowContext {
private WindowState state;
public WindowContext(WindowState state) {
this.state = state;
}
public WindowState getState() {
return state;
}
public void setState(WindowState state) {
this.state = state;
}
public void switchState() {
this.state.handle();
}
}
/*
* state (State) model Behavioral pattern
* It changes both the state of the object and its behavior
* Change your behavior based on your state
*/
public class Test {
public static void main(String[] args) {
/*
* In this case the There are only two state values, which are controlled by the state class itself
* The control of the state value can also be left to the client to set
*/
WindowContext context = new WindowContext(new WindowState(" window "));
context.switchState();
context.switchState();
context.switchState();
context.switchState();
}
}
Switch to window state
Switch to full screen
Switch to window state
Switch to full screen
Policy pattern example
/**
* Commodity sales promotion
* This class is: the class that receives cash
*/
public interface ICashSuper {
double acceptCash(double money);
}
/**
* Normal cash collection
* @author stone
*
*/
public class CashNormal implements ICashSuper {
@Override
public double acceptCash(double money) {
return money;
}
}
/**
* Discounted cash
* @author stone
*
*/
public class CashRebate implements ICashSuper {
private double rebate; // discount
public CashRebate (double rebate) {
this.rebate = rebate;
}
@Override
public double acceptCash(double money) {
return new BigDecimal(money * rebate / 10).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
}
}
/**
* Benefit cashback cash
* @author stone
*
*/
public class CashReturn implements ICashSuper {
private double moneyCondition; // The minimum amount of cash back
private double returnMoney; // The amount
public CashReturn(double moneyCondition, double returnMoney) {
this.moneyCondition = moneyCondition;
this.returnMoney = returnMoney;
}
@Override
public double acceptCash(double money) {// Multiple rebate
if (money >= moneyCondition) {
return money - Math.floor(money / moneyCondition) * returnMoney;
} else {
return money;
}
}
}
/**
* According to the passed policy class, perform the corresponding behavior
*/
public class CashContext {
private ICashSuper casher;
public CashContext() {
}
public CashContext(ICashSuper casher) {
this.casher = casher;
}
public void setCasher(ICashSuper casher) {
this.casher = casher;
}
// Depending on the specific policy object, its algorithmic behavior is called
public double acceptCash(double money) {
return this.casher.acceptCash(money);
}
}
public class Test {
public static void main(String[] args) {
double money = 998; // The original price
CashContext cashContext = new CashContext(new CashNormal());
System.out.println(" The original price: " + cashContext.acceptCash(money)); // usually strategy
cashContext.setCasher(new CashRebate(8.5));
System.out.println(" play 85 Fold: " + cashContext.acceptCash(money)); // discount strategy 85 fold
cashContext.setCasher(new CashReturn(300, 50));
System.out.println(" full 300 return 50 : " + cashContext.acceptCash(money)); // Cash back strategy full 300 return 50
}
}
/**
* Use of state
*/
public class WindowContext {
private WindowState state;
public WindowContext(WindowState state) {
this.state = state;
}
public WindowState getState() {
return state;
}
public void setState(WindowState state) {
this.state = state;
}
public void switchState() {
this.state.handle();
}
}
0
The difference between a policy pattern and a state pattern
We have seen that the two patterns are structurally very similar, but there are still differences. Here are some key differences between them.
This is all about the difference between the policy pattern and the state pattern in Java. As I said, they look very similar in the UML diagram, both following the open close principle and encapsulating behavior. The policy pattern is used to encapsulate algorithms or policies that are provided to the Context object at runtime as parameters or composite objects, while the state pattern is used to manage state migration.