NOTE

State Pattern

The state pattern selects different processing logic according to the current state, with Java and Go examples.

Software Architecture & EngineeringCreated Updated 1 min readhistorical

This is a historical learning note and may contain outdated or incomplete understanding.

1. Definition

Select different processing logic according to different states; using if/else is too cumbersome.

The difference from the strategy pattern is that each strategy in the strategy pattern is used to accomplish the same thing, while the state pattern is used to accomplish different things.

2. UML

PlantUML 图表

3. Java

3.1. Client

public class Client
{
    public static void main(String[] args)
    {
        Context context = new Context();
        context.setStatus(new FreeStatus());
        context.setStatus(new BookedStatus());
    }
}

3.2. Context

public class Context
{
    private Status status;

    public void setStatus(Status status)
    {
        // Change the state and trigger the behavior for that state
        this.status = status;
        this.status.handle();
    }
}

3.3. State

public interface Status
{
    void handle();
}
public class BookedStatus implements Status
{
    @Override
    public void handle()
    {
        System.out.println("room reserved");
    }
}
public class FreeStatus implements Status
{
    @Override
    public void handle()
    {
        System.out.println("room available");
    }
}

4. Golang

4.1. State

/* Ticket processing state */
type ITicketStatus interface {
	Handle()
}

// Process the ticket
type ProcessTicketStatus struct {
}

func NewProcessTicketStatus() *ProcessTicketStatus {
	return &ProcessTicketStatus{}
}

func (p *ProcessTicketStatus) Handle() {
	fmt.Println("process ticket")
}

/* Report ticket */
type ReportTicketStatus struct {
}

func NewReportTicketStatus() *ReportTicketStatus {
	return &ReportTicketStatus{}
}

func (r *ReportTicketStatus) Handle() {
	fmt.Println("report ticket")
}

4.2. State Management Class

/* Ticket-state management class */
type TicketStatusContext struct {
	status ITicketStatus
}

func NewTicketStatusContext() *TicketStatusContext {
	return &TicketStatusContext{}
}

func (t *TicketStatusContext) Status() ITicketStatus {
	return t.status
}

func (t *TicketStatusContext) SetStatus(status ITicketStatus) {
	t.status = status
}

4.3. Client

func main() {
	context := 状态模式.NewTicketStatusContext()

	context.SetStatus(状态模式.NewReportTicketStatus())
	context.Status().Handle()

	context.SetStatus(状态模式.NewProcessTicketStatus())
	context.Status().Handle()
}

Discussion

Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub