myapp/
│── domain/ # Чистый домен (сущности + бизнес-логика)
│ ├── user.go
│ ├── user_repository.go
│ ├── user_service.go
│── adapter/ # Адаптеры для инфраструктуры
│ ├── user_repository.go
│ ├── user_event_publisher.go
│── infrastructure/ # Реализации
│ ├── postgres.go
│ ├── kafka.go
│── main.go # Главная точка входа
Created
March 28, 2025 07:45
-
-
Save andrsj/836e91afdc622771dc829a2dbb96092a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package adapter | |
import "myapp/domain" | |
type MessageBrokerClient interface { | |
Publish(topic string, message []byte) error | |
} | |
type UserEventPublisherAdapter struct { | |
client MessageBrokerClient | |
} | |
func NewUserEventPublisherAdapter(client MessageBrokerClient) *UserEventPublisherAdapter { | |
return &UserEventPublisherAdapter{client: client} | |
} | |
func (p *UserEventPublisherAdapter) PublishUserCreated(user *domain.User) error { | |
msg := []byte("User created: " + user.Name) | |
return p.client.Publish("user.events", msg) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package adapter | |
import ( | |
"myapp/domain" | |
) | |
type DatabaseClient interface { | |
QueryUserByID(id int) (*domain.User, error) | |
InsertUser(user *domain.User) error | |
} | |
type UserRepositoryAdapter struct { | |
client DatabaseClient | |
} | |
func NewUserRepositoryAdapter(client DatabaseClient) *UserRepositoryAdapter { | |
return &UserRepositoryAdapter{client: client} | |
} | |
func (r *UserRepositoryAdapter) GetByID(id int) (*domain.User, error) { | |
return r.client.QueryUserByID(id) | |
} | |
func (r *UserRepositoryAdapter) Save(user *domain.User) error { | |
return r.client.InsertUser(user) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package domain | |
type User struct { | |
ID int | |
Name string | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package domain | |
type UserRepository interface { | |
GetByID(id int) (*User, error) | |
Save(user *User) error | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package domain | |
type UserService struct { | |
repo UserRepository | |
publisher EventPublisher | |
} | |
type EventPublisher interface { | |
PublishUserCreated(user *User) error | |
} | |
func NewUserService(repo UserRepository, publisher EventPublisher) *UserService { | |
return &UserService{repo: repo, publisher: publisher} | |
} | |
func (s *UserService) RegisterUser(name string) (*User, error) { | |
user := &User{Name: name} | |
err := s.repo.Save(user) | |
if err != nil { | |
return nil, err | |
} | |
err = s.publisher.PublishUserCreated(user) | |
if err != nil { | |
return nil, err | |
} | |
return user, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package infrastructure | |
import ( | |
".../kafka" | |
) | |
type KafkaClient struct { | |
producer *kafka.Producer | |
} | |
func NewKafkaClient(brokers string) (*KafkaClient, error) { | |
producer, err := kafka.NewProducer(&kafka.ConfigMap{"bootstrap.servers": brokers}) | |
if err != nil { | |
return nil, err | |
} | |
return &KafkaClient{producer: producer}, nil | |
} | |
func (k *KafkaClient) Publish(topic string, message []byte) error { | |
return k.producer.Produce(&kafka.Message{ | |
TopicPartition: kafka.TopicPartition{Topic: &topic, Partition: kafka.PartitionAny}, | |
Value: message, | |
}, nil) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package infrastructure | |
import ( | |
"database/sql" | |
"myapp/domain" | |
_ "github.com/lib/pq" | |
) | |
type PostgresClient struct { | |
db *sql.DB | |
} | |
func NewPostgresClient(connString string) (*PostgresClient, error) { | |
db, err := sql.Open("postgres", connString) | |
if err != nil { | |
return nil, err | |
} | |
return &PostgresClient{db: db}, nil | |
} | |
func (p *PostgresClient) QueryUserByID(id int) (*domain.User, error) { | |
var user domain.User | |
err := p.db.QueryRow("SELECT id, name FROM users WHERE id = $1", id). | |
Scan(&user.ID, &user.Name) | |
if err != nil { | |
return nil, err | |
} | |
return &user, nil | |
} | |
func (p *PostgresClient) InsertUser(user *domain.User) error { | |
_, err := p.db.Exec("INSERT INTO users (id, name) VALUES ($1, $2)", user.ID, user.Name) | |
return err | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"log" | |
"myapp/adapter" | |
"myapp/domain" | |
"myapp/infrastructure" | |
) | |
func main() { | |
dbClient, err := infrastructure.NewPostgresClient("postgres://user:password@localhost:5432/mydb?sslmode=disable") | |
if err != nil { | |
log.Fatal(err) | |
} | |
kafkaClient, err := infrastructure.NewKafkaClient("localhost:9092") | |
if err != nil { | |
log.Fatal(err) | |
} | |
userRepo := adapter.NewUserRepositoryAdapter(dbClient) | |
eventPublisher := adapter.NewUserEventPublisherAdapter(kafkaClient) | |
userService := domain.NewUserService(userRepo, eventPublisher) | |
user, err := userService.RegisterUser("Andrii") | |
if err != nil { | |
log.Fatal(err) | |
} | |
log.Println("Created user:", user) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment