Middle · Architecture and systems

Package boundaries and clean code

What makes a Go package a useful boundary rather than an extra folder?

Try explaining this aloud before opening the answer. State your assumptions and trace a boundary case.

Reveal a strong answer
  1. A package owns a cohesive responsibility and exposes a small contract. Name it for its domain or capability, not a vague layer such as utils. Keep dependency direction acyclic and hide implementation details with unexported identifiers and internal where appropriate.

  2. Place small interfaces where behavior is consumed. Concrete types are often sufficient until there are actual alternate implementations or testing boundaries. Constructor parameters should make resource and configuration dependencies visible.

  3. Clean code reduces the reader's work: meaningful names, short error paths, explicit ownership and focused tests. A uniform line count or one interface per struct is not a substitute for a clear invariant.

Common trap

Moving every type into its own package increases navigation and can create artificial dependency cycles.

Try it

Split a handler that validates input, charges a card and writes an order. Where is the transaction policy?

Worked solution

Keep HTTP decoding at the edge and payment/order orchestration in an application operation. Let storage expose the needed atomic operation. Do not pretend a database transaction can atomically include an arbitrary remote payment call; model retries and reconciliation.

Change the constraint

How would you avoid making your domain depend on a database driver type?

How did you do?

Self-assessment, not a compiler pass or interview score. Explain the reasoning unaided before marking understood.

Not marked. Progress stays on this browser, separate from course completion.

Primary references

Checked 2026-10-20. Use documentation for your pinned runtime, driver and tool version.