0Pricing
Go Academy · Lekcja

Wzorce konstruktorów

Tworzenie konstruktorów zgodnych z idiomami Go

Wzorce konstruktorów to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.

Po co konstruktory?

Go nie ma słowa kluczowego new dla typów ani konstruktorów klas. Przyjęta konwencja to funkcja o nazwie New..., która sprawdza poprawność danych wejściowych i zwraca zainicjalizowaną wartość lub wskaźnik.

Prosta funkcja New

Należy zwrócić wskaźnik, aby zapewnić pracę wywołującego ze współdzieloną instancją:

package main
import "fmt"

type Server struct {
    Host string
    Port int
}

func NewServer(host string, port int) *Server {
    return &Server{Host: host, Port: port}
}

func main() {
    s := NewServer("localhost", 8080)
    fmt.Println(s.Host, s.Port)
}

Walidacja w konstruktorach

Konstruktory są dobrym miejscem do sprawdzania poprawności danych wejściowych i zwracania błędu:

package main
import ("errors"; "fmt")

type Config struct{ Workers int }

func NewConfig(workers int) (*Config, error) {
    if workers < 1 {
        return nil, errors.New("workers must be >= 1")
    }
    return &Config{Workers: workers}, nil
}

func main() {
    c, err := NewConfig(4)
    fmt.Println(c, err)
}

Wzorzec opcji funkcyjnych

Wzorzec opcji funkcyjnych pozwala dodawać opcjonalną konfigurację bez naruszania API:

package main
import "fmt"

type Server struct{ host string; port int; timeout int }
type Option func(*Server)

func WithPort(p int) Option    { return func(s *Server) { s.port = p } }
func WithTimeout(t int) Option { return func(s *Server) { s.timeout = t } }

func NewServer(host string, opts ...Option) *Server {
    s := &Server{host: host, port: 8080, timeout: 30}
    for _, o := range opts { o(s) }
    return s
}

func main() {
    s := NewServer("localhost", WithPort(9090), WithTimeout(60))
    fmt.Println(s.port, s.timeout)
}

Wzorzec buildera

W przypadku złożonych obiektów wzorzec buildera łączy metody ustawiające i zwraca wynik:

package main
import "fmt"

type QueryBuilder struct{ table, where string; limit int }

func (q *QueryBuilder) Table(t string) *QueryBuilder { q.table = t; return q }
func (q *QueryBuilder) Where(w string) *QueryBuilder { q.where = w; return q }
func (q *QueryBuilder) Limit(n int)   *QueryBuilder { q.limit = n; return q }
func (q *QueryBuilder) Build() string {
    return fmt.Sprintf("SELECT * FROM %s WHERE %s LIMIT %d", q.table, q.where, q.limit)
}

func main() {
    sql := (&QueryBuilder{}).Table("users").Where("age>18").Limit(10).Build()
    fmt.Println(sql)
}

Zwracanie wartości a wskaźnika

Należy zwracać wartość, gdy struct jest mały i niezmienny, a wskaźnik, gdy struct jest duży, zmienny lub implementuje interfejsy:

  • Małe struct konfiguracyjne → wartość
  • Obiekty przechowujące stan (serwer, klient, pula) → wskaźnik
  • Jeśli implementowany jest interfejs za pomocą receiverów wskaźnikowych → wskaźnik

Wzorzec wartości domyślnych

Należy użyć funkcji ustawiającej wartości domyślne lub literału struct, aby ustawić rozsądne wartości domyślne przed zastosowaniem opcji:

package main
import "fmt"

type Cache struct{ maxSize int; ttlSecs int }

func defaultCache() Cache { return Cache{maxSize: 100, ttlSecs: 300} }

func NewCache(opts ...func(*Cache)) *Cache {
    c := defaultCache()
    for _, o := range opts { o(&c) }
    return &c
}

func main() {
    c := NewCache(func(c *Cache) { c.maxSize = 500 })
    fmt.Println(c.maxSize, c.ttlSecs) // 500 300
}

Wzorzec singletonu

Należy użyć sync.Once, aby dokładnie raz zainicjalizować współdzielony zasób:

package main
import ("fmt"; "sync")

type DB struct{ DSN string }

var (
    instance *DB
    once     sync.Once
)

func GetDB(dsn string) *DB {
    once.Do(func() { instance = &DB{DSN: dsn} })
    return instance
}

func main() {
    db1 := GetDB("postgres://...")
    db2 := GetDB("ignored")
    fmt.Println(db1 == db2) // true
}

Testowanie konstruktorów

Konstruktory zwracające błędy można łatwo testować:

package main
import ("errors"; "fmt")

type Pool struct{ size int }

func NewPool(size int) (*Pool, error) {
    if size <= 0 { return nil, errors.New("size must be positive") }
    return &Pool{size: size}, nil
}

func main() {
    _, err := NewPool(-1)
    fmt.Println(err) // size must be positive
    p, _ := NewPool(5)
    fmt.Println(p.size) // 5
}

Unikanie init()

Funkcje init() uruchamiają się automatycznie i trudno je testować. Zamiast niejawnej inicjalizacji w init() należy preferować jawne konstruktory zwracające błędy.

Szybkie sprawdzenie

Co zapewnia wzorzec opcji funkcyjnych?

Podsumowanie: wzorce konstruktorów

Najważniejsze informacje:

  • Należy używać funkcji New... jako konstruktorów
  • W przypadku niepowodzenia walidacji należy zwracać błędy
  • Opcje funkcyjne służą do elastycznej konfiguracji opcjonalnej
  • Wzorzec buildera sprawdza się w przypadku złożonych obiektów zapytań i konfiguracji
  • Należy preferować jawne konstruktory zamiast init()

Polecenie do przećwiczenia

Należy zaimplementować konstruktor NewHTTPClient z użyciem opcji funkcyjnych. Należy obsłużyć opcje WithTimeout, WithBaseURL oraz WithMaxRetries.

Często zadawane pytania

Czy lekcja „Wzorce konstruktorów” jest bezpłatna?

Tak — pełny tekst „Wzorce konstruktorów” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Wzorce konstruktorów”?

Tworzenie konstruktorów zgodnych z idiomami Go Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Go Academy?

Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Wzorce konstruktorów”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?

Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Definiowanie i używanie struktur
  2. Metody struktur
  3. Wzorce konstruktorów
  4. Struktury anonimowe i kompozycja
← Powrót do Go Academy