SlideShare a Scribd company logo
Object Calisthenics
Elton Minetto
@eminetto
O que é?
Conjunto de boas práticas e regras de
programação que podem ser aplicadas para
melhorar a qualidade do código
Introduzido por Jeff Bay e publicado no livro
ThoughtWorks Anthology
Inicialmente criadas tendo como base a
linguagem Java e adaptações são necessárias
para outros ambientes
Então...
Object Calisthenics
Code Calisthenics
Object Calisthenics em Go
• One level of indentation per method
• One level of indentation per method
• Don’t use the ELSE keyword
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One dot per line
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One dot per line
• Don’t abbreviate
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One dot per line
• Don’t abbreviate
• Keep all classes less than 50 lines
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One dot per line
• Don’t abbreviate
• Keep all classes less than 50 lines
• No classes with more than two instance variables
• One level of indentation per method
• Don’t use the ELSE keyword
• Wrap all primitives and Strings in classes
• First class collections
• One dot per line
• Don’t abbreviate
• Keep all classes less than 50 lines
• No classes with more than two instance variables
• No getters or setters
One level of indentation per method
Aplicar esta regra permite que o nosso código
seja mais legível
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;)
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
// level 0
for i := 0; i < 10; i++ {
// level 1
for j := 0; j < 10; j++ {
// level 2
buffer.WriteString(b.data[i][j])
}
buffer.WriteString("n")
}
return buffer.String()
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;)
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
// level 0
for i := 0; i < 10; i++ {
// level 1
for j := 0; j < 10; j++ {
// level 2
buffer.WriteString(b.data[i][j])
}
buffer.WriteString("n")
}
return buffer.String()
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;)
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
// level 0
for i := 0; i < 10; i++ {
// level 1
for j := 0; j < 10; j++ {
// level 2
buffer.WriteString(b.data[i][j])
}
buffer.WriteString("n")
}
return buffer.String()
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {}
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
b.collectRows(buffer)
return buffer.String()
}
func (b *board) collectRows(buffer *bytes.Buffer) {
for i := 0; i < 10; i++ {
b.collectRow(buffer, i)
}
}
func (b *board) collectRow(buffer *bytes.Buffer, row int) {
for j := 0; j < 10; j++ {
buffer.WriteString(b.data[row][j])
}
buffer.WriteString("n")
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {}
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
b.collectRows(buffer)
return buffer.String()
}
func (b *board) collectRows(buffer *bytes.Buffer) {
for i := 0; i < 10; i++ {
b.collectRow(buffer, i)
}
}
func (b *board) collectRow(buffer *bytes.Buffer, row int) {
for j := 0; j < 10; j++ {
buffer.WriteString(b.data[row][j])
}
buffer.WriteString("n")
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {}
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
b.collectRows(buffer)
return buffer.String()
}
func (b *board) collectRows(buffer *bytes.Buffer) {
for i := 0; i < 10; i++ {
b.collectRow(buffer, i)
}
}
func (b *board) collectRow(buffer *bytes.Buffer, row int) {
for j := 0; j < 10; j++ {
buffer.WriteString(b.data[row][j])
}
buffer.WriteString("n")
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {}
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
b.collectRows(buffer)
return buffer.String()
}
func (b *board) collectRows(buffer *bytes.Buffer) {
for i := 0; i < 10; i++ {
b.collectRow(buffer, i)
}
}
func (b *board) collectRow(buffer *bytes.Buffer, row int) {
for j := 0; j < 10; j++ {
buffer.WriteString(b.data[row][j])
}
buffer.WriteString("n")
}
type board struct {
data [][]string
}
func NewBoard(data [][]string) *board {}
func (b *board) Board() string {
var buffer = &bytes.Buffer{}
b.collectRows(buffer)
return buffer.String()
}
func (b *board) collectRows(buffer *bytes.Buffer) {
for i := 0; i < 10; i++ {
b.collectRow(buffer, i)
}
}
func (b *board) collectRow(buffer *bytes.Buffer, row int) {
for j := 0; j < 10; j++ {
buffer.WriteString(b.data[row][j])
}
buffer.WriteString("n")
}
Object Calisthenics em Go
Object Calisthenics em Go
Don’t use the ELSE keyword
A ideia deste item é evitarmos o uso da palavra
chave else, gerando um código limpo e mais
rápido, pois tem menos fluxos de execução
type loginService struct {
userRepository *repository.UserRepository
}
func NewLoginService() *loginService {
return &loginService{
userRepository: repository.NewUserRepository(),
}
}
func (l *loginService) Login(userName, password string) {
if l.userRepository.IsValid(userName, password) {
redirect("homepage")
} else {
addFlash("error", "Bad credentials")
redirect("login")
}
}
func redirect(page string) {}
func addFlash(msgType, msg string) {}
type loginService struct {
userRepository *repository.UserRepository
}
func NewLoginService() *loginService {
return &loginService{
userRepository: repository.NewUserRepository(),
}
}
func (l *loginService) Login(userName, password string) {
if l.userRepository.IsValid(userName, password) {
redirect("homepage")
} else {
addFlash("error", "Bad credentials")
redirect("login")
}
}
func redirect(page string) {}
func addFlash(msgType, msg string) {}
type loginService struct {
userRepository *repository.UserRepository
}
func NewLoginService() *loginService {
return &loginService{
userRepository: repository.NewUserRepository(),
}
}
func (l *loginService) Login(userName, password string) {
if l.userRepository.IsValid(userName, password) {
redirect("homepage")
} else {
addFlash("error", "Bad credentials")
redirect("login")
}
}
func redirect(page string) {}
func addFlash(msgType, msg string) {}
func (l *loginService) Login(userName, password string) {
if l.userRepository.IsValid(userName, password) {
redirect("homepage")
return
}
addFlash("error", "Bad credentials")
redirect("login")
}
Wrap all primitives and Strings in classes
Tipos primitivos que possuem comportamento
devem ser encapsulados, no nosso caso, em
structs ou types e não em classes. Desta forma,
a lógica do comportamento fica encapsulado e
de fácil manutenção
type order struct {
pid int64
cid int64
}
func CreateOrder(pid int64, cid int64) order {
return order{
pid: pid, cid: cid,
}
}
func (o order) Submit() (int64, error) {
// do some logic
return int64(3252345234), nil
}
type order struct {
pid int64
cid int64
}
func CreateOrder(pid int64, cid int64) order {
return order{
pid: pid, cid: cid,
}
}
func (o order) Submit() (int64, error) {
// do some logic
return int64(3252345234), nil
}
type order struct {
pid int64
cid int64
}
func CreateOrder(pid int64, cid int64) order {
return order{
pid: pid, cid: cid,
}
}
func (o order) Submit() (int64, error) {
// do some logic
return int64(3252345234), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
type order struct {
pid productID
cid customerID
}
type productID int64
// some functions on productID type
type customerID int64
// some functions on customerID type
type orderID int64
func (oid orderID) String() string {
return strconv.FormatInt(int64(oid), 10)
}
// some other functions on orderID type
func CreateOrder(pid int64, cid int64) order {
return order{
pid: productID(pid), cid: customerID(cid),
}
}
func (o order) Submit() (orderID, error) {
// do some logic
return orderID(int64(3252345234)), nil
}
First class collections
Se você tiver um conjunto de elementos e
quiser manipulá-los, crie uma estrutura
dedicada para essa coleção. Assim
comportamentos relacionados à coleção serão
implementados por sua própria estrutura
como filtros, ordenação, storage, etc.
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type person struct {
name string
friends []string
}
func NewPerson(name string) *person {
return &person{
name: name,
friends: []string{},
}
}
func (p *person) AddFriend(name string) {
p.friends = append(p.friends, name)
}
func (p *person) RemoveFriend(name string) {
new := []string{}
for _, friend := range p.friends {
if friend != name {
new = append(new, friend)
}
}
p.friends = new
}
func (p *person) GetFriends() []string {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s %v", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
type friends struct {
data []string
}
type person struct {
name string
friends *friends
}
func NewFriends() *friends {} //código omitido pra ficar legal no slide ;)
func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;)
func (f *friends) String() string {} //código omitido pra ficar legal no slide ;)
func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;)
func (p *person) AddFriend(name string) {
p.friends.Add(name)
}
func (p *person) RemoveFriend(name string) {
p.friends.Remove(name)
}
func (p *person) GetFriends() *friends {
return p.friends
}
func (p *person) String() string {
return fmt.Sprintf("%s [%v]", p.name, p.friends)
}
One dot per line
Essa regra cita que você não deve encadear
funções e sim usar as que fazem parte do
mesmo contexto.
type board struct {
Squares []*square
}
type square struct {
current *piece
}
type piece struct {
name string
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
buffer.WriteString(s.current.name)
}
return buffer.String()
}
https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
type board struct {
Squares []*square
}
type square struct {
current *piece
}
type piece struct {
name string
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
buffer.WriteString(s.current.name)
}
return buffer.String()
}
https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
type board struct {
Squares []*square
}
type square struct {
current *piece
}
type piece struct {
name string
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
buffer.WriteString(s.current.name)
}
return buffer.String()
}
https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
Lei de Demeter
Lei de Demeter
• Cada unidade deve ter conhecimento
limitado sobre outras unidades: apenas
unidades próximas se relacionam.
Lei de Demeter
• Cada unidade deve ter conhecimento
limitado sobre outras unidades: apenas
unidades próximas se relacionam.
• Cada unidade deve apenas conversar com
seus amigos; Não fale com estranhos.
Lei de Demeter
• Cada unidade deve ter conhecimento
limitado sobre outras unidades: apenas
unidades próximas se relacionam.
• Cada unidade deve apenas conversar com
seus amigos; Não fale com estranhos.
• Apenas fale com seus amigos imediatos.
type board struct {
Squares []*square
}
type square struct {
current *piece
}
func (s *square) addTo(buffer *bytes.Buffer) {
s.current.addTo(buffer)
}
type piece struct {
name string
}
func (p *piece) addTo(buffer *bytes.Buffer) {
buffer.WriteString(p.name)
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
s.addTo(buffer)
}
return buffer.String()
}
https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
type board struct {
Squares []*square
}
type square struct {
current *piece
}
func (s *square) addTo(buffer *bytes.Buffer) {
s.current.addTo(buffer)
}
type piece struct {
name string
}
func (p *piece) addTo(buffer *bytes.Buffer) {
buffer.WriteString(p.name)
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
s.addTo(buffer)
}
return buffer.String()
}
https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
type board struct {
Squares []*square
}
type square struct {
current *piece
}
func (s *square) addTo(buffer *bytes.Buffer) {
s.current.addTo(buffer)
}
type piece struct {
name string
}
func (p *piece) addTo(buffer *bytes.Buffer) {
buffer.WriteString(p.name)
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
s.addTo(buffer)
}
return buffer.String()
}
https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
type board struct {
Squares []*square
}
type square struct {
current *piece
}
func (s *square) addTo(buffer *bytes.Buffer) {
s.current.addTo(buffer)
}
type piece struct {
name string
}
func (p *piece) addTo(buffer *bytes.Buffer) {
buffer.WriteString(p.name)
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
s.addTo(buffer)
}
return buffer.String()
}
https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
type board struct {
Squares []*square
}
type square struct {
current *piece
}
func (s *square) addTo(buffer *bytes.Buffer) {
s.current.addTo(buffer)
}
type piece struct {
name string
}
func (p *piece) addTo(buffer *bytes.Buffer) {
buffer.WriteString(p.name)
}
func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide
func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide
func NewBoard() *board {}//código omitido pra ficar legal no slide
func (b *board) BoardRepresentation() string {
var buffer = &bytes.Buffer{}
for _, s := range b.Squares {
s.addTo(buffer)
}
return buffer.String()
}
https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
Don’t abbreviate
Esta regra é uma das que não se aplica
diretamente a Go. A comunidade tem suas
próprias regras para a criação de nomes de
variáveis, inclusive razões por usarmos nomes
menores. Recomendo a leitura deste capítulo
do ótimo Practical Go: Real world advice for
writing maintainable Go programs
Keep all classes less than 50 lines
Apesar de não existir o conceito de classes em
Go, a ideia desta regra é que as entidades
sejam pequenas. Podemos adaptar a ideia para
criarmos structs e interfaces pequenas e que
podem ser usadas, via composição, para formar
componentes maiores
type Repository interface {
Find(id entity.ID) (*entity.User, error)
FindByEmail(email string) (*entity.User, error)
FindByChangePasswordHash(hash string) (*entity.User, error)
FindByValidationHash(hash string) (*entity.User, error)
FindByChallengeSubmissionHash(hash string) (*entity.User, error)
FindByNickname(nickname string) (*entity.User, error)
FindAll() ([]*entity.User, error)
Update(user *entity.User) error
Store(user *entity.User) (entity.ID, error)
Remove(id entity.ID) error
}
type Reader interface {
Find(id entity.ID) (*entity.User, error)
FindByEmail(email string) (*entity.User, error)
FindByChangePasswordHash(hash string) (*entity.User, error)
FindByValidationHash(hash string) (*entity.User, error)
FindByChallengeSubmissionHash(hash string) (*entity.User, error)
FindByNickname(nickname string) (*entity.User, error)
FindAll() ([]*entity.User, error)
}
type Writer interface {
Update(user *entity.User) error
Store(user *entity.User) (entity.ID, error)
Remove(id entity.ID) error
}
type Repository interface {
Reader
Writer
}
No classes with more than two
instance variables
Esta regra não parece fazer sentido em Go
No Getters/Setters
Não é um costume da comunidade usar este
recurso, como pode ser visto neste tópico do
Effective Go
Referências
Os códigos completos e demais referências
podem ser encontrados neste post:
Object Calisthenics em Golang
https://eltonminetto.dev
https://codenation.dev
@eminetto

More Related Content

What's hot

Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
Learning from other's mistakes: Data-driven code analysis
Learning from other's mistakes: Data-driven code analysisLearning from other's mistakes: Data-driven code analysis
Learning from other's mistakes: Data-driven code analysis
Andreas Dewes
 
C++ L09-Classes Part2
C++ L09-Classes Part2C++ L09-Classes Part2
C++ L09-Classes Part2
Mohammad Shaker
 
C# Starter L02-Classes and Objects
C# Starter L02-Classes and ObjectsC# Starter L02-Classes and Objects
C# Starter L02-Classes and Objects
Mohammad Shaker
 
Java ppt Gandhi Ravi (gandhiri@gmail.com)
Java ppt  Gandhi Ravi  (gandhiri@gmail.com)Java ppt  Gandhi Ravi  (gandhiri@gmail.com)
Java ppt Gandhi Ravi (gandhiri@gmail.com)
Gandhi Ravi
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
Geshan Manandhar
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web Developers
Joris Verbogt
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
allanh0526
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
HamletDRC
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
Sergey Platonov
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
HamletDRC
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with Groovy
Iván López Martín
 
C# Starter L03-Utilities
C# Starter L03-UtilitiesC# Starter L03-Utilities
C# Starter L03-Utilities
Mohammad Shaker
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java Developers
Bob McCune
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
Jano Suchal
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
kwatch
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
HamletDRC
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-Collections
Mohammad Shaker
 
Clean code
Clean codeClean code
Clean code
Henrique Smoco
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
Nascenia IT
 

What's hot (20)

Clean code
Clean codeClean code
Clean code
 
Learning from other's mistakes: Data-driven code analysis
Learning from other's mistakes: Data-driven code analysisLearning from other's mistakes: Data-driven code analysis
Learning from other's mistakes: Data-driven code analysis
 
C++ L09-Classes Part2
C++ L09-Classes Part2C++ L09-Classes Part2
C++ L09-Classes Part2
 
C# Starter L02-Classes and Objects
C# Starter L02-Classes and ObjectsC# Starter L02-Classes and Objects
C# Starter L02-Classes and Objects
 
Java ppt Gandhi Ravi (gandhiri@gmail.com)
Java ppt  Gandhi Ravi  (gandhiri@gmail.com)Java ppt  Gandhi Ravi  (gandhiri@gmail.com)
Java ppt Gandhi Ravi (gandhiri@gmail.com)
 
7 rules of simple and maintainable code
7 rules of simple and maintainable code7 rules of simple and maintainable code
7 rules of simple and maintainable code
 
Objective-C Crash Course for Web Developers
Objective-C Crash Course for Web DevelopersObjective-C Crash Course for Web Developers
Objective-C Crash Course for Web Developers
 
From android/java to swift (3)
From android/java to swift (3)From android/java to swift (3)
From android/java to swift (3)
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Алексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуляАлексей Кутумов, Вектор с нуля
Алексей Кутумов, Вектор с нуля
 
AST Transformations at JFokus
AST Transformations at JFokusAST Transformations at JFokus
AST Transformations at JFokus
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with Groovy
 
C# Starter L03-Utilities
C# Starter L03-UtilitiesC# Starter L03-Utilities
C# Starter L03-Utilities
 
Objective-C for Java Developers
Objective-C for Java DevelopersObjective-C for Java Developers
Objective-C for Java Developers
 
Postobjektové programovanie v Ruby
Postobjektové programovanie v RubyPostobjektové programovanie v Ruby
Postobjektové programovanie v Ruby
 
Fantastic DSL in Python
Fantastic DSL in PythonFantastic DSL in Python
Fantastic DSL in Python
 
AST Transformations
AST TransformationsAST Transformations
AST Transformations
 
C# Starter L04-Collections
C# Starter L04-CollectionsC# Starter L04-Collections
C# Starter L04-Collections
 
Clean code
Clean codeClean code
Clean code
 
Advanced JavaScript
Advanced JavaScriptAdvanced JavaScript
Advanced JavaScript
 

Similar to Object Calisthenics em Go

Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
Rafael Winterhalter
 
Getting Input from User
Getting Input from UserGetting Input from User
Getting Input from User
Lovely Professional University
 
Unit-2 Getting Input from User.pptx
Unit-2 Getting Input from User.pptxUnit-2 Getting Input from User.pptx
Unit-2 Getting Input from User.pptx
Lovely Professional University
 
devLink - What's New in C# 4?
devLink - What's New in C# 4?devLink - What's New in C# 4?
devLink - What's New in C# 4?
Kevin Pilch
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
ShriKant Vashishtha
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
Jevgeni Kabanov
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
Julien Truffaut
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
Yandex
 
Linq intro
Linq introLinq intro
Linq intro
Bình Trọng Án
 
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
Lucas Arruda
 
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdfNeed help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
actexerode
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
R696
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
GeorgePeterBanyard
 
PostThis
PostThisPostThis
PostThis
testingphase
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
Kiev ALT.NET
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
intelliyole
 
Interpreter Case Study - Design Patterns
Interpreter Case Study - Design PatternsInterpreter Case Study - Design Patterns
Interpreter Case Study - Design Patterns
CodeOps Technologies LLP
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
Movel
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0
Frost
 
C++ Nested loops, matrix and fuctions.pdf
C++ Nested loops, matrix and fuctions.pdfC++ Nested loops, matrix and fuctions.pdf
C++ Nested loops, matrix and fuctions.pdf
yamew16788
 

Similar to Object Calisthenics em Go (20)

Making Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVMMaking Java more dynamic: runtime code generation for the JVM
Making Java more dynamic: runtime code generation for the JVM
 
Getting Input from User
Getting Input from UserGetting Input from User
Getting Input from User
 
Unit-2 Getting Input from User.pptx
Unit-2 Getting Input from User.pptxUnit-2 Getting Input from User.pptx
Unit-2 Getting Input from User.pptx
 
devLink - What's New in C# 4?
devLink - What's New in C# 4?devLink - What's New in C# 4?
devLink - What's New in C# 4?
 
Working effectively with legacy code
Working effectively with legacy codeWorking effectively with legacy code
Working effectively with legacy code
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!Implicit parameters, when to use them (or not)!
Implicit parameters, when to use them (or not)!
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
Linq intro
Linq introLinq intro
Linq intro
 
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics1st CI&T Lightning Talks: Writing better code with Object Calisthenics
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
 
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdfNeed help with the TODO's (DONE IN C++) #pragma once   #include -funct.pdf
Need help with the TODO's (DONE IN C++) #pragma once #include -funct.pdf
 
Clean code _v2003
 Clean code _v2003 Clean code _v2003
Clean code _v2003
 
PHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing InsanityPHP 8: Process & Fixing Insanity
PHP 8: Process & Fixing Insanity
 
PostThis
PostThisPostThis
PostThis
 
Micro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicateMicro-ORM Introduction - Don't overcomplicate
Micro-ORM Introduction - Don't overcomplicate
 
The Kotlin Programming Language
The Kotlin Programming LanguageThe Kotlin Programming Language
The Kotlin Programming Language
 
Interpreter Case Study - Design Patterns
Interpreter Case Study - Design PatternsInterpreter Case Study - Design Patterns
Interpreter Case Study - Design Patterns
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0Building an api using golang and postgre sql v1.0
Building an api using golang and postgre sql v1.0
 
C++ Nested loops, matrix and fuctions.pdf
C++ Nested loops, matrix and fuctions.pdfC++ Nested loops, matrix and fuctions.pdf
C++ Nested loops, matrix and fuctions.pdf
 

More from Elton Minetto

Go e Microserviços - Nascidos um para o outro
Go e Microserviços - Nascidos um para o outroGo e Microserviços - Nascidos um para o outro
Go e Microserviços - Nascidos um para o outro
Elton Minetto
 
Programar != desenvolver software (v2)
Programar != desenvolver software (v2)Programar != desenvolver software (v2)
Programar != desenvolver software (v2)
Elton Minetto
 
Gerenciando uma startup no Github Projects
Gerenciando uma startup no Github ProjectsGerenciando uma startup no Github Projects
Gerenciando uma startup no Github Projects
Elton Minetto
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
Elton Minetto
 
Serverless em Go
Serverless em GoServerless em Go
Serverless em Go
Elton Minetto
 
JAMstack
JAMstackJAMstack
JAMstack
Elton Minetto
 
Clean architecture em Go - v2
Clean architecture em Go - v2Clean architecture em Go - v2
Clean architecture em Go - v2
Elton Minetto
 
Programar != desenvolver software
Programar != desenvolver softwareProgramar != desenvolver software
Programar != desenvolver software
Elton Minetto
 
Clean Architecture em PHP
Clean Architecture em PHPClean Architecture em PHP
Clean Architecture em PHP
Elton Minetto
 
Clean Architecture in Golang
Clean Architecture in GolangClean Architecture in Golang
Clean Architecture in Golang
Elton Minetto
 
A jornada do desenvolvedor
A jornada do desenvolvedorA jornada do desenvolvedor
A jornada do desenvolvedor
Elton Minetto
 
Product and Technology
Product and TechnologyProduct and Technology
Product and Technology
Elton Minetto
 
Code:Nation Tech Stack
Code:Nation Tech StackCode:Nation Tech Stack
Code:Nation Tech Stack
Elton Minetto
 
Modernizando projetos legados usando APIs
Modernizando projetos legados usando APIsModernizando projetos legados usando APIs
Modernizando projetos legados usando APIs
Elton Minetto
 
12 factor in the PHP world
12 factor in the PHP world12 factor in the PHP world
12 factor in the PHP world
Elton Minetto
 
Building APIs using Go
Building APIs using GoBuilding APIs using Go
Building APIs using Go
Elton Minetto
 
Start you
Start youStart you
Start you
Elton Minetto
 
O case da Compufácil e AWS
O case da Compufácil e AWSO case da Compufácil e AWS
O case da Compufácil e AWS
Elton Minetto
 
Introdução a Go
Introdução a GoIntrodução a Go
Introdução a Go
Elton Minetto
 
Como extrair métricas do Trello
Como extrair métricas do TrelloComo extrair métricas do Trello
Como extrair métricas do Trello
Elton Minetto
 

More from Elton Minetto (20)

Go e Microserviços - Nascidos um para o outro
Go e Microserviços - Nascidos um para o outroGo e Microserviços - Nascidos um para o outro
Go e Microserviços - Nascidos um para o outro
 
Programar != desenvolver software (v2)
Programar != desenvolver software (v2)Programar != desenvolver software (v2)
Programar != desenvolver software (v2)
 
Gerenciando uma startup no Github Projects
Gerenciando uma startup no Github ProjectsGerenciando uma startup no Github Projects
Gerenciando uma startup no Github Projects
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Serverless em Go
Serverless em GoServerless em Go
Serverless em Go
 
JAMstack
JAMstackJAMstack
JAMstack
 
Clean architecture em Go - v2
Clean architecture em Go - v2Clean architecture em Go - v2
Clean architecture em Go - v2
 
Programar != desenvolver software
Programar != desenvolver softwareProgramar != desenvolver software
Programar != desenvolver software
 
Clean Architecture em PHP
Clean Architecture em PHPClean Architecture em PHP
Clean Architecture em PHP
 
Clean Architecture in Golang
Clean Architecture in GolangClean Architecture in Golang
Clean Architecture in Golang
 
A jornada do desenvolvedor
A jornada do desenvolvedorA jornada do desenvolvedor
A jornada do desenvolvedor
 
Product and Technology
Product and TechnologyProduct and Technology
Product and Technology
 
Code:Nation Tech Stack
Code:Nation Tech StackCode:Nation Tech Stack
Code:Nation Tech Stack
 
Modernizando projetos legados usando APIs
Modernizando projetos legados usando APIsModernizando projetos legados usando APIs
Modernizando projetos legados usando APIs
 
12 factor in the PHP world
12 factor in the PHP world12 factor in the PHP world
12 factor in the PHP world
 
Building APIs using Go
Building APIs using GoBuilding APIs using Go
Building APIs using Go
 
Start you
Start youStart you
Start you
 
O case da Compufácil e AWS
O case da Compufácil e AWSO case da Compufácil e AWS
O case da Compufácil e AWS
 
Introdução a Go
Introdução a GoIntrodução a Go
Introdução a Go
 
Como extrair métricas do Trello
Como extrair métricas do TrelloComo extrair métricas do Trello
Como extrair métricas do Trello
 

Recently uploaded

SAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple SoftwareSAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple Software
Zyple Software
 
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical SystemsInflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
Inflectra
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
attueb
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
3610stuck
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
Srinivas Dukka
 
當測試開始左移
當測試開始左移當測試開始左移
當測試開始左移
Jersey (CHE-PING) Su
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
kalichargn70th171
 
welcome to presentation on Google Apps
welcome to   presentation on Google Appswelcome to   presentation on Google Apps
welcome to presentation on Google Apps
AsifKarimJim
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
bhumivarma35300
 
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
kiara pandey
 
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech
 
React Native vs Flutter - SSTech System
React Native vs Flutter  - SSTech SystemReact Native vs Flutter  - SSTech System
React Native vs Flutter - SSTech System
SSTech System
 
Authentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptxAuthentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptx
DEMONDUOS
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
ashiklo9823
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
45unexpected
 
BATber53 AWS Modernize your applications with purpose-built AWS databases
BATber53 AWS Modernize your applications with purpose-built AWS databasesBATber53 AWS Modernize your applications with purpose-built AWS databases
BATber53 AWS Modernize your applications with purpose-built AWS databases
BATbern
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
neshakor5152
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
andrehoraa
 
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
aslasdfmkhan4750
 
Prada Group Reports Strong Growth in First Quarter …
Prada Group Reports Strong Growth in First Quarter …Prada Group Reports Strong Growth in First Quarter …
Prada Group Reports Strong Growth in First Quarter …
908dutch
 

Recently uploaded (20)

SAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple SoftwareSAP implementation steps PDF - Zyple Software
SAP implementation steps PDF - Zyple Software
 
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical SystemsInflectraCON 360: Risk-Based Testing for Mission Critical Systems
InflectraCON 360: Risk-Based Testing for Mission Critical Systems
 
GT degree offer diploma Transcript
GT degree offer diploma TranscriptGT degree offer diploma Transcript
GT degree offer diploma Transcript
 
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
Mumbai Girls Call Mumbai 🎈🔥9930687706 🔥💋🎈 Provide Best And Top Girl Service A...
 
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
AWS DevOps-Tutorial CHANAKYA SRIYAN DUKKA.
 
當測試開始左移
當測試開始左移當測試開始左移
當測試開始左移
 
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdfA Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
A Step-by-Step Guide to Selecting the Right Automated Software Testing Tools.pdf
 
welcome to presentation on Google Apps
welcome to   presentation on Google Appswelcome to   presentation on Google Apps
welcome to presentation on Google Apps
 
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
Independent Girls call Service Pune 000XX00000 Provide Best And Top Girl Serv...
 
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9930687706 Unlimited Short Providing Girls Servic...
 
Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.Mobile App Development Company in Noida - Drona Infotech.
Mobile App Development Company in Noida - Drona Infotech.
 
React Native vs Flutter - SSTech System
React Native vs Flutter  - SSTech SystemReact Native vs Flutter  - SSTech System
React Native vs Flutter - SSTech System
 
Authentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptxAuthentication Review-June -2024 AP & TS.pptx
Authentication Review-June -2024 AP & TS.pptx
 
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
Vip Girls Call ServiCe Hyderabad 0000000000 Pooja Best High Class Hyderabad A...
 
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
Celebrity Girls Call Mumbai 9920725232 Unlimited Short Providing Girls Servic...
 
BATber53 AWS Modernize your applications with purpose-built AWS databases
BATber53 AWS Modernize your applications with purpose-built AWS databasesBATber53 AWS Modernize your applications with purpose-built AWS databases
BATber53 AWS Modernize your applications with purpose-built AWS databases
 
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in CityGirls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
Girls Call Mysore 000XX00000 Provide Best And Top Girl Service And No1 in City
 
Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)Predicting Test Results without Execution (FSE 2024)
Predicting Test Results without Execution (FSE 2024)
 
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
Independent Girls Call ServiCe Hyderabad 0000000000 Tanisha Best High Class H...
 
Prada Group Reports Strong Growth in First Quarter …
Prada Group Reports Strong Growth in First Quarter …Prada Group Reports Strong Growth in First Quarter …
Prada Group Reports Strong Growth in First Quarter …
 

Object Calisthenics em Go

  • 3. Conjunto de boas práticas e regras de programação que podem ser aplicadas para melhorar a qualidade do código
  • 4. Introduzido por Jeff Bay e publicado no livro ThoughtWorks Anthology
  • 5. Inicialmente criadas tendo como base a linguagem Java e adaptações são necessárias para outros ambientes
  • 10. • One level of indentation per method
  • 11. • One level of indentation per method • Don’t use the ELSE keyword
  • 12. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes
  • 13. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections
  • 14. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections • One dot per line
  • 15. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections • One dot per line • Don’t abbreviate
  • 16. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections • One dot per line • Don’t abbreviate • Keep all classes less than 50 lines
  • 17. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections • One dot per line • Don’t abbreviate • Keep all classes less than 50 lines • No classes with more than two instance variables
  • 18. • One level of indentation per method • Don’t use the ELSE keyword • Wrap all primitives and Strings in classes • First class collections • One dot per line • Don’t abbreviate • Keep all classes less than 50 lines • No classes with more than two instance variables • No getters or setters
  • 19. One level of indentation per method Aplicar esta regra permite que o nosso código seja mais legível
  • 20. type board struct { data [][]string } func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;) func (b *board) Board() string { var buffer = &bytes.Buffer{} // level 0 for i := 0; i < 10; i++ { // level 1 for j := 0; j < 10; j++ { // level 2 buffer.WriteString(b.data[i][j]) } buffer.WriteString("n") } return buffer.String() }
  • 21. type board struct { data [][]string } func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;) func (b *board) Board() string { var buffer = &bytes.Buffer{} // level 0 for i := 0; i < 10; i++ { // level 1 for j := 0; j < 10; j++ { // level 2 buffer.WriteString(b.data[i][j]) } buffer.WriteString("n") } return buffer.String() }
  • 22. type board struct { data [][]string } func NewBoard(data [][]string) *board {} //código omitido pra ficar legal no slide ;) func (b *board) Board() string { var buffer = &bytes.Buffer{} // level 0 for i := 0; i < 10; i++ { // level 1 for j := 0; j < 10; j++ { // level 2 buffer.WriteString(b.data[i][j]) } buffer.WriteString("n") } return buffer.String() }
  • 23. type board struct { data [][]string } func NewBoard(data [][]string) *board {} func (b *board) Board() string { var buffer = &bytes.Buffer{} b.collectRows(buffer) return buffer.String() } func (b *board) collectRows(buffer *bytes.Buffer) { for i := 0; i < 10; i++ { b.collectRow(buffer, i) } } func (b *board) collectRow(buffer *bytes.Buffer, row int) { for j := 0; j < 10; j++ { buffer.WriteString(b.data[row][j]) } buffer.WriteString("n") }
  • 24. type board struct { data [][]string } func NewBoard(data [][]string) *board {} func (b *board) Board() string { var buffer = &bytes.Buffer{} b.collectRows(buffer) return buffer.String() } func (b *board) collectRows(buffer *bytes.Buffer) { for i := 0; i < 10; i++ { b.collectRow(buffer, i) } } func (b *board) collectRow(buffer *bytes.Buffer, row int) { for j := 0; j < 10; j++ { buffer.WriteString(b.data[row][j]) } buffer.WriteString("n") }
  • 25. type board struct { data [][]string } func NewBoard(data [][]string) *board {} func (b *board) Board() string { var buffer = &bytes.Buffer{} b.collectRows(buffer) return buffer.String() } func (b *board) collectRows(buffer *bytes.Buffer) { for i := 0; i < 10; i++ { b.collectRow(buffer, i) } } func (b *board) collectRow(buffer *bytes.Buffer, row int) { for j := 0; j < 10; j++ { buffer.WriteString(b.data[row][j]) } buffer.WriteString("n") }
  • 26. type board struct { data [][]string } func NewBoard(data [][]string) *board {} func (b *board) Board() string { var buffer = &bytes.Buffer{} b.collectRows(buffer) return buffer.String() } func (b *board) collectRows(buffer *bytes.Buffer) { for i := 0; i < 10; i++ { b.collectRow(buffer, i) } } func (b *board) collectRow(buffer *bytes.Buffer, row int) { for j := 0; j < 10; j++ { buffer.WriteString(b.data[row][j]) } buffer.WriteString("n") }
  • 27. type board struct { data [][]string } func NewBoard(data [][]string) *board {} func (b *board) Board() string { var buffer = &bytes.Buffer{} b.collectRows(buffer) return buffer.String() } func (b *board) collectRows(buffer *bytes.Buffer) { for i := 0; i < 10; i++ { b.collectRow(buffer, i) } } func (b *board) collectRow(buffer *bytes.Buffer, row int) { for j := 0; j < 10; j++ { buffer.WriteString(b.data[row][j]) } buffer.WriteString("n") }
  • 30. Don’t use the ELSE keyword A ideia deste item é evitarmos o uso da palavra chave else, gerando um código limpo e mais rápido, pois tem menos fluxos de execução
  • 31. type loginService struct { userRepository *repository.UserRepository } func NewLoginService() *loginService { return &loginService{ userRepository: repository.NewUserRepository(), } } func (l *loginService) Login(userName, password string) { if l.userRepository.IsValid(userName, password) { redirect("homepage") } else { addFlash("error", "Bad credentials") redirect("login") } } func redirect(page string) {} func addFlash(msgType, msg string) {}
  • 32. type loginService struct { userRepository *repository.UserRepository } func NewLoginService() *loginService { return &loginService{ userRepository: repository.NewUserRepository(), } } func (l *loginService) Login(userName, password string) { if l.userRepository.IsValid(userName, password) { redirect("homepage") } else { addFlash("error", "Bad credentials") redirect("login") } } func redirect(page string) {} func addFlash(msgType, msg string) {}
  • 33. type loginService struct { userRepository *repository.UserRepository } func NewLoginService() *loginService { return &loginService{ userRepository: repository.NewUserRepository(), } } func (l *loginService) Login(userName, password string) { if l.userRepository.IsValid(userName, password) { redirect("homepage") } else { addFlash("error", "Bad credentials") redirect("login") } } func redirect(page string) {} func addFlash(msgType, msg string) {}
  • 34. func (l *loginService) Login(userName, password string) { if l.userRepository.IsValid(userName, password) { redirect("homepage") return } addFlash("error", "Bad credentials") redirect("login") }
  • 35. Wrap all primitives and Strings in classes Tipos primitivos que possuem comportamento devem ser encapsulados, no nosso caso, em structs ou types e não em classes. Desta forma, a lógica do comportamento fica encapsulado e de fácil manutenção
  • 36. type order struct { pid int64 cid int64 } func CreateOrder(pid int64, cid int64) order { return order{ pid: pid, cid: cid, } } func (o order) Submit() (int64, error) { // do some logic return int64(3252345234), nil }
  • 37. type order struct { pid int64 cid int64 } func CreateOrder(pid int64, cid int64) order { return order{ pid: pid, cid: cid, } } func (o order) Submit() (int64, error) { // do some logic return int64(3252345234), nil }
  • 38. type order struct { pid int64 cid int64 } func CreateOrder(pid int64, cid int64) order { return order{ pid: pid, cid: cid, } } func (o order) Submit() (int64, error) { // do some logic return int64(3252345234), nil }
  • 39. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 40. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 41. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 42. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 43. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 44. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 45. type order struct { pid productID cid customerID } type productID int64 // some functions on productID type type customerID int64 // some functions on customerID type type orderID int64 func (oid orderID) String() string { return strconv.FormatInt(int64(oid), 10) } // some other functions on orderID type func CreateOrder(pid int64, cid int64) order { return order{ pid: productID(pid), cid: customerID(cid), } } func (o order) Submit() (orderID, error) { // do some logic return orderID(int64(3252345234)), nil }
  • 46. First class collections Se você tiver um conjunto de elementos e quiser manipulá-los, crie uma estrutura dedicada para essa coleção. Assim comportamentos relacionados à coleção serão implementados por sua própria estrutura como filtros, ordenação, storage, etc.
  • 47. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 48. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 49. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 50. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 51. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 52. type person struct { name string friends []string } func NewPerson(name string) *person { return &person{ name: name, friends: []string{}, } } func (p *person) AddFriend(name string) { p.friends = append(p.friends, name) } func (p *person) RemoveFriend(name string) { new := []string{} for _, friend := range p.friends { if friend != name { new = append(new, friend) } } p.friends = new } func (p *person) GetFriends() []string { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s %v", p.name, p.friends) }
  • 53. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 54. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 55. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 56. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 57. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 58. type friends struct { data []string } type person struct { name string friends *friends } func NewFriends() *friends {} //código omitido pra ficar legal no slide ;) func (f *friends) Add(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) Remove(name string) {} //código omitido pra ficar legal no slide ;) func (f *friends) String() string {} //código omitido pra ficar legal no slide ;) func NewPerson(name string) *person {} //código omitido pra ficar legal no slide ;) func (p *person) AddFriend(name string) { p.friends.Add(name) } func (p *person) RemoveFriend(name string) { p.friends.Remove(name) } func (p *person) GetFriends() *friends { return p.friends } func (p *person) String() string { return fmt.Sprintf("%s [%v]", p.name, p.friends) }
  • 59. One dot per line Essa regra cita que você não deve encadear funções e sim usar as que fazem parte do mesmo contexto.
  • 60. type board struct { Squares []*square } type square struct { current *piece } type piece struct { name string } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { buffer.WriteString(s.current.name) } return buffer.String() } https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
  • 61. type board struct { Squares []*square } type square struct { current *piece } type piece struct { name string } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { buffer.WriteString(s.current.name) } return buffer.String() } https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
  • 62. type board struct { Squares []*square } type square struct { current *piece } type piece struct { name string } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { buffer.WriteString(s.current.name) } return buffer.String() } https://gist.github.com/eminetto/af2ac89e79f945ff2ace8c71b3299a52
  • 64. Lei de Demeter • Cada unidade deve ter conhecimento limitado sobre outras unidades: apenas unidades próximas se relacionam.
  • 65. Lei de Demeter • Cada unidade deve ter conhecimento limitado sobre outras unidades: apenas unidades próximas se relacionam. • Cada unidade deve apenas conversar com seus amigos; Não fale com estranhos.
  • 66. Lei de Demeter • Cada unidade deve ter conhecimento limitado sobre outras unidades: apenas unidades próximas se relacionam. • Cada unidade deve apenas conversar com seus amigos; Não fale com estranhos. • Apenas fale com seus amigos imediatos.
  • 67. type board struct { Squares []*square } type square struct { current *piece } func (s *square) addTo(buffer *bytes.Buffer) { s.current.addTo(buffer) } type piece struct { name string } func (p *piece) addTo(buffer *bytes.Buffer) { buffer.WriteString(p.name) } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { s.addTo(buffer) } return buffer.String() } https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
  • 68. type board struct { Squares []*square } type square struct { current *piece } func (s *square) addTo(buffer *bytes.Buffer) { s.current.addTo(buffer) } type piece struct { name string } func (p *piece) addTo(buffer *bytes.Buffer) { buffer.WriteString(p.name) } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { s.addTo(buffer) } return buffer.String() } https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
  • 69. type board struct { Squares []*square } type square struct { current *piece } func (s *square) addTo(buffer *bytes.Buffer) { s.current.addTo(buffer) } type piece struct { name string } func (p *piece) addTo(buffer *bytes.Buffer) { buffer.WriteString(p.name) } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { s.addTo(buffer) } return buffer.String() } https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
  • 70. type board struct { Squares []*square } type square struct { current *piece } func (s *square) addTo(buffer *bytes.Buffer) { s.current.addTo(buffer) } type piece struct { name string } func (p *piece) addTo(buffer *bytes.Buffer) { buffer.WriteString(p.name) } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { s.addTo(buffer) } return buffer.String() } https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
  • 71. type board struct { Squares []*square } type square struct { current *piece } func (s *square) addTo(buffer *bytes.Buffer) { s.current.addTo(buffer) } type piece struct { name string } func (p *piece) addTo(buffer *bytes.Buffer) { buffer.WriteString(p.name) } func NewSquare(piece *piece) *square {}//código omitido pra ficar legal no slide func NewPiece(name string) *piece {}//código omitido pra ficar legal no slide func NewBoard() *board {}//código omitido pra ficar legal no slide func (b *board) BoardRepresentation() string { var buffer = &bytes.Buffer{} for _, s := range b.Squares { s.addTo(buffer) } return buffer.String() } https://gist.github.com/eminetto/6a0ad46da38e2e7d068aec7fdc492b49
  • 72. Don’t abbreviate Esta regra é uma das que não se aplica diretamente a Go. A comunidade tem suas próprias regras para a criação de nomes de variáveis, inclusive razões por usarmos nomes menores. Recomendo a leitura deste capítulo do ótimo Practical Go: Real world advice for writing maintainable Go programs
  • 73. Keep all classes less than 50 lines Apesar de não existir o conceito de classes em Go, a ideia desta regra é que as entidades sejam pequenas. Podemos adaptar a ideia para criarmos structs e interfaces pequenas e que podem ser usadas, via composição, para formar componentes maiores
  • 74. type Repository interface { Find(id entity.ID) (*entity.User, error) FindByEmail(email string) (*entity.User, error) FindByChangePasswordHash(hash string) (*entity.User, error) FindByValidationHash(hash string) (*entity.User, error) FindByChallengeSubmissionHash(hash string) (*entity.User, error) FindByNickname(nickname string) (*entity.User, error) FindAll() ([]*entity.User, error) Update(user *entity.User) error Store(user *entity.User) (entity.ID, error) Remove(id entity.ID) error }
  • 75. type Reader interface { Find(id entity.ID) (*entity.User, error) FindByEmail(email string) (*entity.User, error) FindByChangePasswordHash(hash string) (*entity.User, error) FindByValidationHash(hash string) (*entity.User, error) FindByChallengeSubmissionHash(hash string) (*entity.User, error) FindByNickname(nickname string) (*entity.User, error) FindAll() ([]*entity.User, error) } type Writer interface { Update(user *entity.User) error Store(user *entity.User) (entity.ID, error) Remove(id entity.ID) error } type Repository interface { Reader Writer }
  • 76. No classes with more than two instance variables Esta regra não parece fazer sentido em Go
  • 77. No Getters/Setters Não é um costume da comunidade usar este recurso, como pode ser visto neste tópico do Effective Go
  • 78. Referências Os códigos completos e demais referências podem ser encontrados neste post: Object Calisthenics em Golang