Skip to content

Instantly share code, notes, and snippets.

@andreleoni
Last active May 16, 2020 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreleoni/e501d4b299b902c4e19ddbf39d5ab0ba to your computer and use it in GitHub Desktop.
Save andreleoni/e501d4b299b902c4e19ddbf39d5ab0ba to your computer and use it in GitHub Desktop.
[Medium] Example of code with principle open-closed with GOLang
package main
import "fmt"
// Product attributes to be filtered
type Color int
const (
red Color = iota
green
blue
)
type Size int
const (
small Size = iota
medium
large
)
type Product struct {
name string
color Color
size Size
}
// Filter structure to filter based on implementation specifications
type Specification interface {
IsSatisfied(p *Product) bool
}
type Filter struct {}
type AndSpecification struct {
first, second Specification
}
func (a AndSpecification) IsSatisfied(p *Product) bool {
return a.first.IsSatisfied(p) && a.second.IsSatisfied(p)
}
func (f *Filter) Filter(products []Product, spec Specification) []*Product {
result := make([]*Product, 0)
for i, v := range products {
if spec.IsSatisfied(&v) {
result = append(result, &products[i])
}
}
return result
}
// Implementation of filters to color and size through the interfaces
type ColorSpecification struct {
color Color
}
func (c ColorSpecification) IsSatisfied(p *Product) bool {
return p.color == c.color
}
type SizeSpecification struct {
size Size
}
func (s SizeSpecification) IsSatisfied(p *Product) bool {
return p.size == s.size
}
func main() {
apple := Product{"Apple", green, small}
tree := Product{"Tree", green, large}
house := Product{"House", blue, large}
products := []Product{apple, tree, house}
f := Filter{}
greenSpecification := ColorSpecification{green}
for _, v := range f.Filter(products, greenSpecification) {
fmt.Printf(" %s is green ", v.name)
}
sizeSpecification := SizeSpecification{large}
lgSpec := AndSpecification{greenSpecification, sizeSpecification}
for _, v := range f.Filter(products, lgSpec) {
fmt.Printf(" %s is large and green ", v.name)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment