# State Design Pattern
###### tags: `Design Pattern` `Code Design`
## What it is for?
This design pattern is mainly used to show different states, a state can have.
:::info
***For example:***
Let's say you have an account, which can be anything.
What kind of states you might have?
* Online/Offline
* Buyer/Seller [If account is for buying platform]
* Student/Teacher/Workers/Director [If account is for school]
:::
#### What if you have different actions for each of them, when doing the same action?
>Let's say you have a button which is **BUY** button. If you press it while being offline, it would probably tell you to log in first to proceed. However, if you are online, then it would just add it to your buying list. [color=#907bf7]
#### Why use state pattern design?
Now, you might be thinking... Why don't we just make 2 classes?
One for online and one for offline?
I had the same question too!
But then think about the amount of if..else you might use!
``` java==
if(status == online){
//Do sth
} else if(status == offline){
//Do sth
}
```
We might end up using it everytime, then we can imagine how fat our code will be.
Here is when **State Pattern Design** becomes useful!
What if you can just do **"instance of State".Action**?
``` java==
State state = new Online();
state.printState();
//I am online!
state = new Offline();
state.printState();
//I am offline!
```
As seen from above, we change our status by assigning a new one, but ++still can access to the methods(functions) using the same way++.
### What do we need to use ++State Design Pattern++?
1. **An Interface** that will be telling us what methods are in common in all states available. [A State Interface]
2. **Classes** which are different states, which will implement the State Interface to decide what will the methods be doing in each state.
3. **State variable** will be created and set a state to it.
#### ++State Interface++
We will insert the methods that are going to be used in each state.
``` java==
public interface StateInterface {
//Insert the methods you want
//your different states to have
void login();
void edit();
void dele();
}
```
#### ++State Classes++
In this case, we might have 3 buttons in main view and we might want to apply different actions depending whether you are online or offline.
Therefore, we have to override all the methods mentioned in interface.
*++Online State Class++*
``` java==
public class OnlineState implements StateInterface{
public OnlineState(){}
@Override
public void login() {
System.out.print("LOG OUT");
}
@Override
public void edit() {
System.out.print("ONLINE EDIT");
}
@Override
public void dele() {
System.out.print("ONLINE DELETE");
}
}
```
*++Offline State Class++*
``` java==
public class OfflineState implements StateInterface{
public OfflineState(){}
@Override
public void login() {
System.out.print("LOG IN");
}
@Override
public void edit() {
System.out.print("OFFLINE EDIT");
}
@Override
public void dele() {
System.out.print("OFFLINE DELETE");
}
}
```
#### ++State Variable++
Below we can see that we can set a state and then later assign the state you are in.
For instance, you will be able to use the methods inside the state you are in.
``` java==
public class StateDesignPattern {
public static void main(String[] args) {
//OFFLINE STATE
StateInterface state = new OfflineState();
state.login();
state.edit();
state.dele();
//ONLINE STATE
state = new OnlineState();
state.login();
state.edit();
state.dele();
}
}
```
### Doubts you might have:
>As you can see in above code, we can keep making a new status whenever we want to change the original status.
But then, **++is that the best choice++**?
>
>I would probably say it is better to have a single status for each status. That means we should avoid making a new one whenever we need it. For instance, I would mix Singleton Design Pattern with State Design Pattern. [color=#907bf7]
``` java==
public class StateDesignPattern {
public static void main(String[] args) {
OnlineState onlineState = OnlineState.getInstance();
OfflineState offlineState = OfflineState.getInstance();
StateInterface state = offlineState;
state.login();
state.edit();
state.dele();
state = onlineState;
state.login();
state.edit();
state.dele();
}
}
```
``` java==
public class OnlineState implements StateInterface{
private OnlineState(){}
private static OnlineState onlineState = new OnlineState();
public static OnlineState getInstance(){
if(onlineState != null){
return onlineState;
} else {
return new OnlineState();
}
}
//Below would be the override methods from interface
}
```
``` java==
public class OfflineState implements StateInterface{
private OfflineState(){}
private static OfflineState offlineState = new OfflineState();
public static OfflineState getInstance(){
if(offlineState != null){
return offlineState;
} else {
return new OfflineState();
}
}
//Below would be the override methods from interface
}
```