This is the 7th day of my participation in Gwen Challenge
The business scenario
Those of you who have studied design patterns often wonder when you are writing code, when will you use your prehistorical powers?
Recently, I happened to meet the most appropriate demand, a brief introduction:
- You need to monitor the device at all times
- You can send up move/down move/stop move instructions to the device
- When the device is offline, it needs to be reconnected and initialized
- During device initialization, obtain device information
- You need to obtain device coordinates when the device is running properly
plan
Following the above requirements, we can easily write code with the following structure:
if (device.getStatus() == Device.Status.OFFLINE) {
// Business code
} else if (device.getStatus() == Device.Status.INIT) {
// Business code}...Copy the code
At first glance, the logic is pretty rigorous, but the reality is that when you move up, you get this bunch of ifs, and it also happens when you move down, when you stop moving
At this point, we should use state mode
When a bunch of identical if statements occur in two or more different methods, we should consider replacing them with State
The difference between state mode and policy mode is that in state mode users cannot perceive and participate in state changes of objects, while in policy mode they can
Write state classes
First, create a BaseState class, basestate.java:
public abstract class BaseState {
Device device;
protected BaseState(Device device) {
this.device = device;
}
/** * Heartbeat link */
public abstract void heartBeat(a);
}
Copy the code
Continue to create an OffLineState inherited from the base state, offlinestate.java:
public class OffLineState extends BaseState {
public OffLineState(Device device) {
super(device);
}
@Override
public void heartBeat(a) {
homing();
}
public void homing(a) {
try {
device.homing();
device.setState(new InitState(device));
} catch (IOException e) {
device.setState(newOffLineState(device)); }}}Copy the code
As you can see, the change in state is internal and is not perceived by the user
Next create the initialization class, initstate.java:
public class InitState extends BaseState {
public InitState(Device device) {
super(device);
}
@Override
public void heartBeat(a) {
try {
if (device.isMove()) {
return;
}
device.setZeroPosition(device.currentPosition());
device.setState(new OnLineState(device));
} catch (IOException e) {
device.setState(newOffLineState(device)); }}}Copy the code
Replace method
Next, we just need to replace the code device.heartbeat () with device.getState().heartbeat () in the actual business logic
I will not repeat the details here, but simply show the author’s business-related codes:
public class Connector {
private static final int INTERVAL = 2000;
@Async
public void connect(Device device) {
try {
while(true) { device.getState().heartBeat(); Thread.sleep(INTERVAL); }}catch(InterruptedException e) { Thread.currentThread().interrupt(); }}}Copy the code
conclusion
Finally, summarize the characteristics of state mode:
- State classes have the same public methods
- The state class has an attribute pointing to the entity class that uses the state
- The status class automatically switches the status internally, and users cannot sense it
- Used to replace large recurring if statements