object oriented programming in go

34
Object-Oriented Programming in Go Go Seoul Meetup 24 January 2015 장재휴 Developer, Purpleworks

Upload: jaehue-jang

Post on 14-Jul-2015

449 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Object oriented programming in go

Object-Oriented Programming inGoGo Seoul Meetup24 January 2015

장재휴Developer, Purpleworks

Page 2: Object oriented programming in go

Who am I

Elandsystems ➜ purpleworks

Ruby, C#, Go

Page 3: Object oriented programming in go

Agenda

OOP in Go

Page 4: Object oriented programming in go

What is "Object Oriented" (wikipedia)

A language is usually considered object-based if it includes the basic capabilitiesfor an object: identity, properties, and attributes

A language is considered object-oriented if it is object-based and also has thecapability of polymorphism and inheritance

Page 5: Object oriented programming in go

Is Go Object-based Language?

Page 6: Object oriented programming in go

What is an "Object" (wikipedia)

An object is an abstract data type that has state(data) and behavior(code)

Page 7: Object oriented programming in go

Object in Go (via Custom Type & Method)

package main

import "fmt"

// Type Declarationtype Item struct {type Item struct { name string price float64 quantity int}

// Method Declarationfunc (t Item) Cost() float64 {func (t Item) Cost() float64 { return t.price * float64(t.quantity)}

// In Actionfunc main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} fmt.Println("cost: ", shirt.Cost())fmt.Println("cost: ", shirt.Cost())} Run

Page 8: Object oriented programming in go

Custom Type of built-in Type

// Type Declarationtype Items []Itemtype Items []Item

// Method Declarationfunc (ts Items) Cost() float64 {func (ts Items) Cost() float64 { var c float64 for _, t := range ts { c += t.Cost() } return c}

// In Actionfunc main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} items := Items{shirt, shoes}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("total cost: ", items.Cost())} Run

Page 9: Object oriented programming in go

Go is Object-based

Via custom type and methods

Page 10: Object oriented programming in go

Is Go Object-oriented Language?

Page 11: Object oriented programming in go

What is "Inheritance" (wikipedia)

Provides reuse of existing objects

Classes are created in hierarchies

Inheritance passes knowledge down!

Page 12: Object oriented programming in go

Inheritance is not good

In Java user group meeting, James Gosling (Java’s inventor) says:

You should avoid implementation inheritance whenever possible.

Page 13: Object oriented programming in go

Go's approach

Go avoided inheritance

Go strictly follows the Composition over inheritance principle

Page 14: Object oriented programming in go

What is Composition

Provides reuse of Objects

One object is declared by containing other objects

Composition pulls knowledge into another

Page 15: Object oriented programming in go

Composition in Go

// Type Declarationtype Item struct { name string price float64 quantity int}

type DiscountItem struct { ItemItem discountRate float64}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3},Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00,10.00, }}

fmt.Println("shoes: ", shoes) fmt.Println("eventShoes: ", eventShoes)} Run

Page 16: Object oriented programming in go

Call Method of Embedded Type

type DiscountItem struct { Item discountRate float64}

// Method Declarationfunc (t Item) Cost() float64 {func (t Item) Cost() float64 { return t.price * float64(t.quantity)return t.price * float64(t.quantity)}}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, }

fmt.Println("cost of shoes: ", shoes.Cost())fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost())fmt.Println("cost of eventShoes: ", eventShoes.Cost())} Run

Page 17: Object oriented programming in go

Method Overriding

// Method Declarationfunc (t Item) Cost() float64 { return t.price * float64(t.quantity)}

func (t DiscountItem) Cost() float64 {func (t DiscountItem) Cost() float64 { return t.Item.Cost() * (1.0 - t.discountRate/100)return t.Item.Cost() * (1.0 - t.discountRate/100)}}

// In Actionfunc main() { shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, }

fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost())} Run

Page 18: Object oriented programming in go

Composition in Go 2

// Type Declaration (embedded field)type Order struct { ItemsItems taxRate float64}

// Overriding Methodsfunc (o Order) Cost() float64 {func (o Order) Cost() float64 { return o.Items.Cost() * (1.0 + o.taxRate/100)}

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} items := Items{shirt, shoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("total cost: ", items.Cost()) fmt.Println("total cost(included Tax): ", order.Cost())} Run

Page 19: Object oriented programming in go

Composition in Go 3

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, } items := Items{shirt, shoes, eventShoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost()) fmt.Println("total cost: ", items.Cost()) fmt.Println("total cost(included Tax): ", order.Cost())} Run

Page 20: Object oriented programming in go

Composition in Go 4

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} shoes := Item{name: "Sports Shoes", price: 30000, quantity: 2} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, } items := Items{shirt, shoes, eventShoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println("cost of shirt: ", shirt.Cost()) fmt.Println("cost of shoes: ", shoes.Cost()) fmt.Println("cost of eventShoes: ", eventShoes.Cost()) fmt.Println("total cost: ", items.Cost()) fmt.Println("total cost(included Tax): ", order.Cost())} Run

Page 21: Object oriented programming in go

What is "Polymorphism" (wikipedia)

The provision of a single interface to entities of different types

Via Generics, Overloading and/or Subtyping

Page 22: Object oriented programming in go

Go’s approach

Go avoided subtyping & overloading

Go does not provide Generics

Polymorphism via interfaces

Page 23: Object oriented programming in go

Interfaces in Go

Interfaces are just sets of methods

Interfaces define behavior (duck typing)

"If something can do this, then it can be used here”

Page 24: Object oriented programming in go

Interfaces in Go

type Rental struct { name string feePerDay float64 periodLength int RentalPeriod}

type RentalPeriod int

const ( Days RentalPeriod = iota Weeks Months)

func (p RentalPeriod) ToDays() int { switch p { case Weeks: return 7 case Months: return 30 default: return 1 }}

Page 25: Object oriented programming in go

Interfaces in Go

func (r Rental) Cost() float64 { return r.feePerDay * float64(r.ToDays()*r.periodLength)}

// Interface Declarationtype Coster interface {type Coster interface { Cost() float64Cost() float64}}

func DisplayCost(c Coster) {func DisplayCost(c Coster) { fmt.Println("cost: ", c.Cost())}

// In Actionfunc main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} video := Rental{"Interstellar", 1000, 3, Days}

fmt.Printf("[%v] ", shirt.name) DisplayCost(shirt)DisplayCost(shirt) fmt.Printf("[%v] ", video.name) DisplayCost(video)DisplayCost(video)} Run

Page 26: Object oriented programming in go

Interfaces in Go 2

// Interface Declarationtype Coster interface { Cost() float64}

// Itemstype Items []Costertype Items []Coster

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} video := Rental{"Interstellar", 1000, 3, Days} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, } items := Items{shirt, video, eventShoes} order := Order{Items: items, taxRate: 10.00}

DisplayCost(shirt) DisplayCost(video) DisplayCost(eventShoes) DisplayCost(items) DisplayCost(order)}

Run

Page 27: Object oriented programming in go

Satisfying Interface of Other Package

fmt.Println

func Println(a ...interface{}) (n int, err error) { return Fprintln(os.Stdout, a...)}

func Fprintln(w io.Writer, a ...interface{}) (n int, err error) { ... // print using Stringer interface ... return}

fmt.Stringer

type Stringer interface { String() string}

Page 28: Object oriented programming in go

Satisfying Interface of Other Package

// Stringerfunc (t Item) String() string { return fmt.Sprintf("[%s] %.0f", t.name, t.Cost())}

func (t Rental) String() string { return fmt.Sprintf("[%s] %.0f", t.name, t.Cost())}

func (t DiscountItem) String() string { return fmt.Sprintf("%s => %.0f(%.0f%s DC)", t.Item.String(), t.Cost(), t.discountRate, "%")}

func (t Items) String() string { return fmt.Sprintf("%d items. total: %.0f", len(t), t.Cost())}

func (o Order) String() string { return fmt.Sprintf("Include Tax: %.0f(tax rate: %.2f%s)", o.Cost(), o.taxRate, "%")}

Page 29: Object oriented programming in go

Satisfying Interface of Other Package

func main() { shirt := Item{name: "Men's Slim-Fit Shirt", price: 25000, quantity: 3} video := Rental{"Interstellar", 1000, 3, Days} eventShoes := DiscountItem{ Item{name: "Women's Walking Shoes", price: 50000, quantity: 3}, 10.00, } items := Items{shirt, video, eventShoes} order := Order{Items: items, taxRate: 10.00}

fmt.Println(shirt) fmt.Println(video) fmt.Println(eventShoes) fmt.Println(items) fmt.Println(order)} Run

Page 30: Object oriented programming in go

Deep into Go's Standard Library

io.Writer interface

// http://godoc.org/io#Writertype Writer interface { Write(p []byte) (n int, err os.Error)}

fmt.Fprintln function

func Fprintln(w io.Writer, a ...interface{}) (n int, err error)

Page 31: Object oriented programming in go

The Power of Interfaces

In handle function, just write to io.Writer object

func handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}

The os.Stdout can be used for io.Writer.

func main() { msg := []string{"hello", "world", "this", "is", "an", "example", "of", "io.Writer"} for _, s := range msg { time.Sleep(100 * time.Millisecond) handle(os.Stdout, s)handle(os.Stdout, s) }} Run

Page 32: Object oriented programming in go

The Power of Interfaces

The http.ResponseWriter can be used for io.Writer.

localhost:4000/hello-world (http://localhost:4000/hello-world)

localhost:4000/this-is-an-example-of-io.Writer (http://localhost:4000/this-is-an-example-of-io.Writer)

func handle(w io.Writer, msg string) { fmt.Fprintln(w, msg)}

func main() { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { handle(w, r.URL.Path[1:])handle(w, r.URL.Path[1:]) }) fmt.Println("start listening on port 4000") http.ListenAndServe(":4000", nil)} Run

Page 33: Object oriented programming in go

Go is Object-Oriented

Page 34: Object oriented programming in go

Thank you

장재휴Developer, [email protected] (mailto:[email protected])