Optional Design Pattern is everywhere in each Open-Source Go Project — gRPC / Opentelemetry

Arshad
2 min readMar 25, 2024

When I was doing projects on gRPC and opentelemetry, both projects are in Go Lang. I see the configuration setup is done in different way which create a curiosity inside me to look into the implementation of the design pattern which is used behind the configuration setup. This design pattern is optional design pattern also known as functional design pattern. I have created a full length video too on the same design pattern: Optional / Functional Design Pattern Go Lang | Used In OpenSource Projects gRPC & Opentelemetry — YouTube

Understanding Functional Options

Functional Options is a design pattern commonly used in Go to create objects with customizable configurations. It leverages the power of first-class functions to allow users to specify various options during object initialization.

Implementation Overview

We’ll create a simplified package manager that allows users to define package attributes such as name, version, description, and dependencies using Functional Options. Here’s an overview of our implementation:

  • Define a Package struct representing a software package.
  • Implement PackageOption as a functional type for modifying package configuration.
  • Define functions like WithVersion, WithDescription, and WithDependencies as Functional Options to set different attributes of the package.
  • Implement NewPackage function to create a new package with the provided options.

Code Implementation

// Package represents a software package
type Package struct {
Name string
Version string
Description string
Dependencies []string
}

// PackageOption represents a function that modifies Package configuration
type PackageOption func(*Package)

// WithVersion sets the package version
func WithVersion(version string) PackageOption {
return func(p *Package) {
p.Version = version
}
}

// WithDescription sets the package description
func WithDescription(description string) PackageOption {
return func(p *Package) {
p.Description = description
}
}

// WithDependencies sets the package dependencies
func WithDependencies(dependencies ...string) PackageOption {
return func(p *Package) {
p.Dependencies = dependencies
}
}

// NewPackage creates a new Package with the provided options
func NewPackage(name string, options ...PackageOption) *Package {
pkg := &Package{
Name: name,
}
for _, option := range options {
option(pkg)
}
return pkg
}

Usage Example

func main() {
// Create a new package with custom options
pkg := NewPackage(
"example-package",
WithVersion("1.0.0"),
WithDescription("This is an example package."),
WithDependencies("dependency1", "dependency2"),
)

// Print package information
fmt.Println("Package Name:", pkg.Name)
fmt.Println("Package Version:", pkg.Version)
fmt.Println("Package Description:", pkg.Description)
fmt.Println("Package Dependencies:", pkg.Dependencies)
}

Functional Options pattern empowers developers to build configurable components in a clean and concise manner, making it a valuable tool in Go programming.

About Me:

  1. CodePiper — YouTube

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Arshad
Arshad

No responses yet

Write a response