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
- Definiowanie i używanie struktur
- Metody struktur
- Wzorce konstruktorów
- Struktury anonimowe i kompozycja