Bài 10: Golang - Nhập Môn Cơ Bản

Bài 10: Golang - Nhập Môn Cơ Bản

  

Creational pattern - Builder

Lý do sử dụng : Khi chúng ta muốn khởi tạo một đối tượng của một cái struct  nhưng struct đó có nhiều thuộc tính và khi chúng ta khởi tạo một cách bình thường thì chúng ta cần phải nắm được kiểu dữ liệu của thuộc tính đó, thứ tự của kiểu dữ liệu và cách chúng ta truyền vào cho chính xác.
Khi chúng ta có một struct mà muốn tạo ra các đối tượng cụ thể hơn cho các struct. Khi chúng ta có một struct mà muốn khởi tạo các đối tượng với đầy đủ các thuộc tính
Thành phần của pattern - Builder:
-    Product : xác định chúng ta cần tạo ra là đối tượng gì?
-    Builder interface: chứa các phương thức dùng để gán các giá trị cho thuộc tính trong product.
-    Concrete Builder: Mỗi Concrete Builder nó sẻ tạo ra các đối tượng cụ thể cho cái Product.
-    Derector: giúp chúng ta liên kết giữa cái Builder interface với nhiều cái Concrete Builder của nó.

- Bây giờ chúng ta sẻ làm một ngôi nhà với golang.

Tạo một dự án mới có cấu trúc như sau:

-    Vào file house.go :
package builder

/*House is truct*/
type House struct {
    windowType string
    doorType   string
    floor      int
}

/* GetWindowType is getter */
func (h *House) GetWindowType() string {
    return h.windowType
}

/* GetDoorType is getter */
func (h *House) GetDoorType() string {
    return h.doorType
}

/* GetNumFloor is getter */
func (h *House) GetNumFloor() int {
    return h.floor
}
-    Vào file director.go:
package builder

/*Director is struct */
type Director struct {
    builder IBuilder
}

/* NewDirector is function */
func NewDirector(b IBuilder) *Director {
    return &Director{
        builder: b,
    }
}

/* SetBuilder is function */
func (d *Director) SetBuilder(b *IBuilder) {
    d.builder = *b
}

/* BuildHouse is function*/
func (d *Director) BuildHouse() House {
    d.builder.setDoorType()
    d.builder.setNumFloor()
    d.builder.setWindowType()
    return d.builder.getHouse()
}
-    Vào file IBuilder.go :
package builder

/*IBuilder is interface*/
type IBuilder interface {
    setWindowType()
    setDoorType()
    setNumFloor()
    getHouse() House
}

/*GetBuilder is function*/
func GetBuilder(builderType string) IBuilder {
    switch builderType {
    case "normal":
        return &normalBuilder{}
    case "igloo":
        return &iglooBuilder{}
    }
    return nil
}
-    Vào file iglooBuilder.go :
package builder

type iglooBuilder struct {
    windowType string
    doorType   string
    floor      int
}

func newIglooBuilder() *iglooBuilder {
    return &iglooBuilder{}
}
func (b *iglooBuilder) setWindowType() {
    b.windowType = "Snow Window"
}
func (b *iglooBuilder) setDoorType() {
    b.doorType = "Snow Door"
}
func (b *iglooBuilder) setNumFloor() {
    b.floor = 1
}
func (b *iglooBuilder) getHouse() House {
    return House{
        doorType:   b.doorType,
        windowType: b.windowType,
        floor:      b.floor,
    }
}
-    Vào file normalBuilder.go :
package builder

type normalBuilder struct {
    windowType string
    doorType   string
    floor      int
}

func newNormalBuilder() *normalBuilder {
    return &normalBuilder{}
}
func (b *normalBuilder) setWindowType() {
    b.windowType = "Wooden window"
}
func (b *normalBuilder) setDoorType() {
    b.doorType = "Wooden Door"
}
func (b *normalBuilder) setNumFloor() {
    b.floor = 2
}
func (b *normalBuilder) getHouse() House {
    return House{
        doorType:   b.doorType,
        windowType: b.windowType,
        floor:      b.floor,
    }
}
-    Vào file main.go :
package main

import (
    "builder/builder"
    "fmt"
)

func main() {
    normalBuilder := builder.GetBuilder("normal")
    iglooBuilder := builder.GetBuilder("igloo")

    director := builder.NewDirector(normalBuilder)
    normalHouse := director.BuildHouse()

    fmt.Printf("Normal House Door Type: %s\n", normalHouse.GetDoorType())
    fmt.Printf("Normal House Window Type: %s\n", normalHouse.GetWindowType())
    fmt.Printf("Normal House Num Type: %d\n", normalHouse.GetNumFloor())

    director.SetBuilder(&iglooBuilder)
    iglooHouse := director.BuildHouse()
    fmt.Printf("\nIgloo House Door Type: %s\n", iglooHouse.GetDoorType())
    fmt.Printf("Igloo House Window Type: %s\n", iglooHouse.GetWindowType())
    fmt.Printf("Igloo House Num Type: %d\n", iglooHouse.GetNumFloor())
}
-    Vào thư mục vừa tạo ban đầu mở cmd lên chạy lệnh go mod init builder để tạo mod giữa các chương trình
-    Chạy lệnh go run main.go
Chạy chương trình bằng cmd:

Creational pattern - Abstract factory 

Thành phần gồm :
-    Abstract product  interface mà nó sẽ định nghĩa các hành vi của sản phẩm này
-    Concrete product : tương ứng với mỗi Abstract product  interface
-    Abstract factory interface : định nghĩa một hành vi của một factory mà chúng ta định nghĩa một cách trừu tượng.
Tạo dự án mới có cấu trúc như sau:
-    Vào file iNode.go :
package prototype

/* Inode is interface */
type INode interface {
    Clone() INode
    Print(s string)
}
-    Vào file file.go:
package prototype

import "fmt"

/* File is struct*/
type File struct {
    Name string
}

/* Print is function*/
func (f *File) Print(s string) {
    fmt.Println(s + f.Name)
}

/* Clone is function */
func (f *File) Clone() INode {
    return &File{Name: f.Name + "_Clone"}
}
-    Vào file folder.go:
package prototype

import "fmt"

/*Folder is struct*/
type Folder struct {
    Childrens []INode
    Name      string
}

/*Print is function*/
func (f *Folder) Print(s string) {
    fmt.Println(s + f.Name + "_Clone")
    for _, i := range f.Childrens {
        i.Print(s + s)
    }
}

/*Clone is function*/
func (f *Folder) Clone() INode {
    cloneFolder := &Folder{Name: f.Name}
    var tempChildrens []INode
    for _, i := range f.Childrens {
        copy := i.Clone()
        tempChildrens = append(tempChildrens, copy)
    }
    cloneFolder.Childrens = tempChildrens
    return cloneFolder
}
-    Vào file main.go:
package main

import (
    "fmt"
    p "prototype/prototype"
)

func main() {
    file1 := &p.File{Name: "File 1"}
    file2 := &p.File{Name: "File 2"}
    file3 := &p.File{Name: "File 3"}
    folder1 := &p.Folder{
        Childrens: []p.INode{file1},
        Name:      "Folder 1",
    }
    folder2 := &p.Folder{
        Childrens: []p.INode{folder1, file2, file3},
        Name:      "Folder 2",
    }

    fmt.Println("\n Printing for Folder 2")
    folder2.Print(" ")
    cloneFolder := folder2.Clone()
    fmt.Println("\n Printing for clone Folder 2")
    cloneFolder.Print(" ")
}

Vào đường dẫn thư mục vừa tạo chạy lệnh :
Chạy tiếp lệnh : 

Behavioral pattern - Chain of responsibility

Khi nào chúng ta cần sử dụng Chain of responsibility?
Đó là khi chúng ta có một đối tượng mà đối tượng này cần chúng ta xử lý một chuỗi các hành vi xử lý tuần tự.
Thành phần của nó gồm:
-    client : là đối tượng chúng ta cần xử lý theo một chuỗi các hành vi và mỗi hành vi thì có một handler
-    handler interface: nó định nghĩa cho chúng ta các hành vi chung cho chuỗi các hành vi mà chúng ta thực hiện. 
trong  handler interface bao gồm 
+    Execute : nơi mà đối với mỗi hành vi chúng ta sẽ thực hiện một hành động gì đó thì chúng ta sẻ cài đặt nó trong này.
+    SetNext: Chúng ta sẻ cài đặt hành vi kế tiếp trong chuỗi hành vi của chúng ta trong này.
-    concrete handler: 
Tạo dự án mới có tên chainlfresponsibility vơi cấu trúc như sau:

-    Vào file patient.go:
package chainlfresponsibility

/*Patient is struct*/
type Patient struct {
    Name              string
    IsRegistered      bool
    IsDoctorChecked   bool
    IsMedicineProvied bool
    IsPaid            bool
}
-    Vào file department.go:
package chainlfresponsibility

/*Department is interface*/
type Department interface {
    Execute(*Patient)
    SetNext(Department)
}
-    Vào file cashier.go:
package chainlfresponsibility

import "fmt"

/*Cashier is struct*/
type Cashier struct {
    next Department
}

/*Execute is function*/
func (c *Cashier) Execute(p *Patient) {
    if p.IsPaid {
        fmt.Println("Patient already paid their bill")
        return
    }
    fmt.Println("Patient is paying the bill")
    p.IsPaid = true
}

/*SetNext is function*/
func (c *Cashier) SetNext(next Department) {
    c.next = next
}
-    Vào file doctor.go:
package chainlfresponsibility

import (
    "fmt"
)

/*Doctor is struct*/
type Doctor struct {
    next Department
}

/*Execute is function*/
func (d *Doctor) Execute(p *Patient) {
    if p.IsDoctorChecked {
        fmt.Println("Patient already cheked by doctor")
        d.next.Execute(p)
        return
    }
    fmt.Println("Doctor is cheked Patient")
    p.IsDoctorChecked = true
    d.next.Execute(p)
}

/*SetNext is function*/
func (d *Doctor) SetNext(next Department) {
    d.next = next
}
-    Vào file medical.go:
package chainlfresponsibility

import "fmt"

/*Medical is struct*/
type Medical struct {
    next Department
}

/*Execute is function*/
func (m *Medical) Execute(p *Patient) {
    if p.IsMedicineProvied {
        fmt.Println("Patient already provided Medicine")
        m.next.Execute(p)
        return
    }
    fmt.Println("we are provided medicine to patient")
    p.IsMedicineProvied = true
    m.next.Execute(p)
}

/*SetNext is function*/
func (m *Medical) SetNext(next Department) {
    m.next = next
}
-    Vào file reception.go:
package chainlfresponsibility

import (
    "fmt"
)

/*Reception is struct*/
type Reception struct {
    next Department
}

/*Execute is function*/
func (r *Reception) Execute(p *Patient) {
    if p.IsRegistered {
        fmt.Println("Patient Registration has already done")
        r.next.Execute(p)
        return
    }
    fmt.Println("Reception Registeting Patient")
    p.IsRegistered = true
    r.next.Execute(p)
}

/*SetNext is function*/
func (r *Reception) SetNext(next Department) {
    r.next = next
}
-    Vào file main.go:
package main

import c "chainlfresponsibility/chainlfresponsibility"

func main() {
    cashier := &c.Cashier{}

    medical := &c.Medical{}
    medical.SetNext(cashier)

    doctor := &c.Doctor{}
    doctor.SetNext(medical)

    reception := &c.Reception{}
    reception.SetNext(doctor)

    patient := &c.Patient{Name: "hung"}
    reception.Execute(patient)
}
Vào đường dẫn thư mục vừa tạo chạy lệnh :
Chạy tiếp lệnh : go run main.go

Behavioral pattern - Command























Đăng nhận xét

0 Nhận xét

myadcash