Menu
Coddy logo textTech

Durum Kalıbı

Coddy'nin GO Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 95 / 107.

State deseni, bir nesnenin iç durumu değiştiğinde davranışını değiştirmesine olanak tanır ve nesne sınıfını değiştirmiş gibi görünür. Template Method algoritma adımlarını kontrol ederken State, duruma özgü davranışı ayrı nesneler içinde kapsüller ve geçerli duruma devreder.

Go'da bir durum arayüzü tanımlar ve farklı davranışları uygulayan somut durumlar oluştururuz:

type State interface {
    Handle(d *Document) string
}

type Document struct {
    state State
}

func (d *Document) SetState(s State) {
    d.state = s
}

func (d *Document) Publish() string {
    return d.state.Handle(d)
}

Her durum ne olacağını ve sırada hangi durumun geleceğini belirler:

type DraftState struct{}

func (s DraftState) Handle(d *Document) string {
    d.SetState(ModerationState{})
    return "Draft submitted for moderation"
}

type ModerationState struct{}

func (s ModerationState) Handle(d *Document) string {
    d.SetState(PublishedState{})
    return "Moderation approved, now published"
}

type PublishedState struct{}

func (s PublishedState) Handle(d *Document) string {
    return "Already published"
}

Aynı yöntem çağrısı, geçerli duruma bağlı olarak farklı sonuçlar üretir:

doc := &Document{state: DraftState{}}

fmt.Println(doc.Publish())  // Taslak moderasyona gönderildi
fmt.Println(doc.Publish())  // Moderasyon onaylandı, şimdi yayınlandı
fmt.Println(doc.Publish())  // Zaten yayınlandı

State, sipariş işleme iş akışları, kullanıcı arayüzü bileşenleri veya davranışın tamamen mevcut duruma bağlı olduğu bağlantı işleyicileri gibi belirgin çalışma modlarına sahip nesneler için idealdir.

challenge icon

Görev

Kolay

State desenini kullanarak bir ticket destek sistemi oluşturalım! Bir destek ticket'ı oluşturacak ve bu ticket'ın açılmasından, üzerinde çalışılmasına ve çözümlenmesine kadar farklı aşamalardan geçmesini sağlayacaksınız; her durum, hangi eylemlerin mümkün olduğunu ve bundan sonra ne olacağını belirleyecek.

Kodunuzu üç dosya arasında düzenleyeceksiniz:

  • state.go: Durum arayüzünüzü ve bir ticket'ın yaşam döngüsündeki her aşamayı temsil eden somut durumları tanımlayın.

    Ticket'ı işleyen ve gerekirse bir sonraki duruma geçiren TicketState metoduna sahip bir Handle(t *Ticket) string arayüzü oluşturun.

    Üç durum uygulayın:

    • OpenState: işlendiğinde ticket'ı InProgressState durumuna geçirir ve Ticket opened, assigning to support team döndürür
    • InProgressState: işlendiğinde ResolvedState durumuna geçer ve Working on ticket, issue resolved döndürür
    • ResolvedState: işlendiğinde aynı durumda kalır ve Ticket already resolved döndürür
  • ticket.go: Mevcut durumu tutan ve davranışı bu duruma devreden ticket yapınızı oluşturun.

    Ticket (string) alanına ve bir ID (TicketState) alanına sahip bir state yapısı oluşturun. Aşağıdaki metotları ekleyin:

    • Ticket'ın mevcut durumunu değiştirmek için SetState(s TicketState)
    • Mevcut durumun Handle metoduna devreden Process() string

    NewTicket(id string) *Ticket durumunda başlayan bir ticket döndüren OpenState kurucusunu oluşturun.

  • main.go: Aynı eylemin ticket'ın mevcut durumuna bağlı olarak nasıl farklı sonuçlar ürettiğini gösterin.

    Bir ticket ID'si ve ticket'ın kaç kez işleneceğini okuyun. Bu ID ile yeni bir ticket oluşturun, ardından Process() metodunu belirtilen sayıda çağırarak her sonucu ayrı bir satıra yazdırın.

Aşağıdaki girdiler sağlanacaktır:

  • 1. satır: Ticket ID
  • 2. satır: Ticket'ın işlenme sayısı

Örneğin, aşağıdaki girdi verildiğinde:

TKT-001
3

Çıktınız şu şekilde olmalıdır:

Ticket opened, assigning to support team
Working on ticket, issue resolved
Ticket already resolved

Ve aşağıdaki girdi verildiğinde:

TKT-500
5

Çıktınız şu şekilde olmalıdır:

Ticket opened, assigning to support team
Working on ticket, issue resolved
Ticket already resolved
Ticket already resolved
Ticket already resolved

Ve aşağıdaki girdi verildiğinde:

ISSUE-42
1

Çıktınız şu şekilde olmalıdır:

Ticket opened, assigning to support team

Aynı ticket üzerinde Process() çağırmanın her seferinde farklı sonuçlar ürettiğine dikkat edin: Ticket durumlar arasında ilerledikçe davranışı değişir. Çözümlendikten sonra, kaç kez işlerseniz işleyin çözümlenmiş olarak kalır. Ticket nesnesi davranışını değiştiriyor gibi görünür, ancak aslında farklı durum nesnelerine devreder!

Kendin dene

package main

import (
	"fmt"
)

func main() {
	// Girdiyi oku
	var ticketID string
	var numProcesses int
	fmt.Scanln(&ticketID)
	fmt.Scanln(&numProcesses)

	// TODO: Verilen ID ile yeni bir bilet oluştur

	// TODO: Bileti belirtilen sayıda işle
	// ve her sonucu ayrı bir satıra yazdır
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Go derleyicisi