Functional Options Pattern에 실행 취소 기능이 설치되어 있음

14593 단어 Go
개시하다
이 글은 Go 추가 캘린더(캘린더 3)의 13일째!
돌이켜보면금년 초에 쓴 기사 한 해 동안의 학습을 바탕으로 자신의 코드를 팩스로 보냈다는 생각이 많았습니다!
전제 조건
원형"복원" 메커니즘 [게임 프로그래밍] [JavaScript 샘플].
"사람"을 사용하여 "하"를 "★"로 운반하는 게임을 상상해 보세요.

전체 맵의 초기 위치1를 x로 설정하면 오른쪽으로 이동하는 함수를 f()로 설정하고 아래로 이동하는 함수를 g()로 설정합니다.
g(g(f(x))) = 
(g \circ g \circ f)(x)
작성 함수를 사용하여 표시할 수 있습니다.
이것은
状態1: f(x) = 初期位置から1つ右に進む
↓
状態2: g(f(x)) = 初期位置から1つ右に進んで、1つ下に進む  = 状態1の位置から1つ下に進む
↓
状態3: g(g(f(x))) = 初期位置から1つ右に進んで、2つ下に進む  = 状態2の位置から1つ下に進む
이런 느낌!
이것을 다음과 같이 실시해 보았다저번.
// 初期位置
var initial Position

// アクション用のスライス
var cmds []Command

cmds = append(cmds, Right()) // 右に1つ進む
cmds = append(cmds, Down()) // 下に1つ進む
cmds = append(cmds, Down()) // 下に1つ進む

// 順にアクションを実行
for _, cmd := range cmds {
    switch f := cmd.(type) {
    case MoveFunc:
        f(initial)
    }
}
'복원'은
1 동작을 하나하나 되돌리는 기능.

이것은 이전의 동작(=절편의 끝을 삭제)을 제거함으로써 이루어진 것이다!
cmds = cmds[:len(cmds)-1] // 1つ戻る
팩시밀리
(Gopher씨의 눈이군요.)
구조체
팩스를 보내기 전에 아래와 같다.
type MapStatus struct {
    pX, pY int // 人の座標
    bX, bY int // 荷物の座標
    mX, mY int // マーク座標
}
팩스로 여기 있습니다.
// MapStatus マップ状態
type MapStatus struct {
    player point // 人の座標
    burden point // 荷物の座標
    mark   point // マーク座標
}

// point 座標
type point struct {
    X, Y int
}
좌표를 만드는 구조체를 통해 처리가 쉬워졌다.
// 人とかぶったら荷物をずらす
if m.player.X == m.burden.X && m.player.Y == m.burden.Y {
    m.burden.X += x
    m.burden.Y += y
}
Functional Options Pattern
본론입니다.
팩스 전에
var cmds []Command
.
.
.
for _, cmd := range cmds {
    switch f := cmd.(type) {
    case MoveFunc:
        f(initial)
    }
}
이렇게 조개로 검사를 해봤어요.
또한 상기cmds의 인터페이스를 만족시키기 위해 반복적으로 시험한 결과
// MoveFunc func(*MapStatus)型
type MoveFunc func(*MapStatus)

// Hoge 空メソッド
func (m MoveFunc) Hoge() {}

// Command 抽象コマンド
type Command interface {
    Hoge()
}
네.(조금 아쉽다)
거기서 팩스 패러디 제작Option하는 것 같아.
// Option func(*MapStatus)型
type Option func(*MapStatus)

// Right 右に1つ進む
func Right() Option {
    return func(m *MapStatus) {
        m.move(1, 0)
    }
}

// Down 下に1つ進む
func Down() Option {
    return func(m *MapStatus) {
        m.move(0, 1)
    }
}

// NewMapStatusWithOption アクション後のマップ状態
func NewMapStatusWithOption(m *MapStatus, options ...Option) *MapStatus {
    for _, option := range options {
        option(m)
    }
    return m
}
많이 멋있어졌어요.
또한 사용처도
player := NewPoint(0, 0)
burden := NewPoint(1, 1)
mark := NewPoint(1, 3)

beforeM := NewMapStatus(player, burden, mark) // 初期位置

afterM := NewMapStatusWithOption(
    beforeM,
    Right(),
    Down(),
    Down())

이렇게 간단하게 썼어요.
관건적인'복원'기능NewMapStatusWithOption과 관련해서는 상대방에게 맡긴 파라미터를 조정하면 된다.
테스트
개정판 여러분의 Go 언어.에 소개된 "Testable Examples"는 이미 시도되었습니다!
이 책에서
Example functions는 Example에서 시작하는 이름으로 정의되며 출력은//Output: 시작하는 주석으로 작성되며 표준 출력의 내용을 테스트할 수 있습니다.
'개정판 2판 여러분의 Go 언어'(p.128)
이런 견해가 있다.
예에 따르다
func ExampleNewMapStatus() {
    player := NewPoint(0, 0)
    burden := NewPoint(1, 1)
    mark := NewPoint(1, 3)

    mapStatus := NewMapStatus(player, burden, mark)

    fmt.Printf("%+v", mapStatus)
    // Output: &{player:{X:0 Y:0} burden:{X:1 Y:1} mark:{X:1 Y:3}}
}
이렇게 실행을 하면...
$ go test -v                                                                                                                                                                           +[main]
=== RUN   ExampleNewMapStatus
--- PASS: ExampleNewMapStatus (0.00s)
PASS
ok      github.com/uh-zz/go-advent-calendar-2021/afterme        0.089s
괜찮은 것 같은데.
끝맺다
이번 기능뿐만 아니라 Functional Options Pattern 느낌이 좋아요.
참고 자료
창고의 미리보기는 이곳에서 만들었어!
원자재다!
"맞다 맞다 이거 갖고 싶다~"
정말?
메모
지도상에서'사람','하','★'의 초기 좌표. 

좋은 웹페이지 즐겨찾기