---
title: No Business Logic In Factory Functions
impact: HIGH
impactDescription: ensures predictable object initialization
tags: factory, initialization, side-effects, patterns, quality
---

## No Business Logic In Factory Functions

Factory functions (e.g., `NewService`) should only initialize state. Side effects in factory functions are unexpected and make testing difficult.

**Incorrect (logic in factory function):**

```go
type UserService struct {
	config Config
}

func NewUserService(configPath string) (*UserService, error) {
	// BAD: Reading files in factory function
	rawConfig, err := os.ReadFile(configPath)
	if err != nil {
		return nil, err
	}
	var config Config
	json.Unmarshal(rawConfig, &config)
	
	// BAD: Network calls/API initialization here
	resp, _ := http.Get("https://api.example.com/init")
	
	// BAD: Logging/side effects
	log.Println("UserService initialized")
	
	return &UserService{config: config}, nil
}
```

**Correct (clear separation):**

```go
type UserService struct {
	config     Config
	httpClient *http.Client
}

func NewUserService(config Config, httpClient *http.Client) *UserService {
	// Only assignment - no side effects
	return &UserService{
		config:     config,
		httpClient: httpClient,
	}
}

// Service initialization in main or a dedicated bootstrapper
func InitializeApp() {
	rawConfig, _ := os.ReadFile("./config.json")
	var config Config
	json.Unmarshal(rawConfig, &config)
	
	httpClient := &http.Client{Timeout: 10 * time.Second}
	
	service := NewUserService(config, httpClient)
	log.Println("UserService ready")
}
```

**Tools:** PR review, Manual review
