손 으로 golang 행동 형 디자인 모델 방문 자 모드

손 으로 golang 행동 형 디자인 모델 방문 자 모드
발단
최근 디자인 모드 복습 담 용 덕 의 < > 본 시리즈 노트 는 골 랑 으로 연습 할 예정 입 니 다.
방문 자 모드
     (Visitor Pattern)                    ,
                      ,
                            ,
         。

                :
(1)      ,                 。
(2)                。
(3)         (  )    ,               。

(       <>)

장면
  • 모 주문 관리 시스템 은 서로 다른 차원 의 통계 에 따라 판매 주문 서 를 분석 해 야 한다
  • .
  • 지역 판매 보고서: 판매 지역 에 따라 판매 상황 을 통계 해 야 한다
  • 품목 별 판매 보고서: 제품 에 따라 판매 상황 을 통계 해 야 한다
  • 방문 자 모델 에 따라 서로 다른 보고 서 를 주문 서 를 판매 하 는 방문 자
  • 로 설계 할 수 있다.
    설계 하 다.
  • 판매 순서: 판매 주문 실체 류
  • ISaleOrder 서비스: 판매 주문 서비스 인터페이스
  • ISaleOrderVisitor: 판매 주문 방문 자
  • tMockSaleOrder 서비스: 가상 판매 주문 서비스, ISaleOrder 서비스 인터페이스 실현
  • CityVisitor: 지역 판매 보고서, 도시 별 총 판매 현황 에 따라 ISaleOrderVisitor 인터페이스
  • 실현
  • ProductVisitor: 품목 판매 보고서, 제품 별 총 판매 현황 에 따라 ISaleOrderVisitor 인터페이스
  • 실현
    유닛 테스트
    visitor_pattern_test.go
    package behavioral_patterns
    
    import (
        "learning/gooop/behavioral_patterns/visitor"
        "testing"
    )
    
    func Test_VisitorPattern(t *testing.T) {
        // prepare sale orders
        service := visitor.MockSaleOrderService
        _ = service.Save(visitor.NewSaleOrder(1, "  ", "  ", "  ", 10))
        _ = service.Save(visitor.NewSaleOrder(2, "  ", "  ", "  ", 20))
        _ = service.Save(visitor.NewSaleOrder(3, "  ", "  ", "  ", 30))
        _ = service.Save(visitor.NewSaleOrder(4, "   ", "  ", "  ", 10))
        _ = service.Save(visitor.NewSaleOrder(5, "   ", "  ", "  ", 20))
        _ = service.Save(visitor.NewSaleOrder(6, "   ", "  ", "  ", 30))
    
        // test CityVisitor
        cv := visitor.NewCityVisitor()
        service.Visit(cv)
        cv.Report()
    
        // test ProductVisitor
        pv := visitor.NewProductVisitor()
        service.Visit(pv)
        pv.Report()
    }

    테스트 출력
    $ go test -v visitor_pattern_test.go 
    === RUN   Test_VisitorPattern
    city=  , sum=60
    city=  , sum=20
    city=  , sum=40
    product=  , sum=40
    product=  , sum=30
    product=  , sum=50
    --- PASS: Test_VisitorPattern (0.00s)
    PASS
    ok      command-line-arguments  0.002s

    SaleOrder.go
    판매 주문서 실체 클래스
    package visitor
    
    
    type SaleOrder struct {
        ID int
        Customer string
        City string
        Product string
        Quantity int
    }
    
    func NewSaleOrder(id int, customer string, city string, product string, quantity int) *SaleOrder {
        return &SaleOrder{
            id, customer,city,product,quantity,
        }
    }

    ISaleOrderService.go
    판매 주문 서비스 인터페이스
    package visitor
    
    type ISaleOrderService interface {
        Save(order *SaleOrder) error
        Visit(visitor ISaleOrderVisitor)
    }

    ISaleOrderVisitor.go
    판매 주문서 방문 자
    package visitor
    
    type ISaleOrderVisitor interface {
        Visit(it *SaleOrder)
        Report()
    }

    tMockSaleOrderService.go
    가상 판매 주문 서비스, ISaleOrderService 인터페이스 실현
    package visitor
    
    
    type tMockSaleOrderService struct {
        orders map[int]*SaleOrder
    }
    
    func newMockSaleOrderService() ISaleOrderService {
        return &tMockSaleOrderService{
            orders: make(map[int]*SaleOrder, 0),
        }
    }
    
    func (me *tMockSaleOrderService) Save(it *SaleOrder) error {
        me.orders[it.ID] = it
        return nil
    }
    
    func (me *tMockSaleOrderService) Visit(visitor ISaleOrderVisitor) {
        for _,v := range me.orders {
            visitor.Visit(v)
        }
    }
    
    var MockSaleOrderService = newMockSaleOrderService()

    CityVisitor.go
    지역 판매 보고서, 도시 종합 판매 상황 에 따라 ISaleOrderVisitor 인터페이스 실현
    package visitor
    
    import "fmt"
    
    type CityVisitor struct {
        cities map[string]int
    }
    
    func NewCityVisitor() ISaleOrderVisitor {
        return &CityVisitor{
            cities: make(map[string]int,0),
        }
    }
    
    func (me *CityVisitor) Visit(it *SaleOrder) {
        n,ok := me.cities[it.City]
        if ok {
            me.cities[it.City] = n + it.Quantity
        } else {
            me.cities[it.City] = it.Quantity
        }
    }
    
    func (me *CityVisitor) Report() {
        for k,v := range me.cities {
            fmt.Printf("city=%s, sum=%v
    ", k, v) } }

    ProductVisitor.go
    품목 판매 보고 서 는 제품 에 따라 판매 상황 을 종합 하여 ISaleOrderVisitor 인 터 페 이 스 를 실현 한다.
    package visitor
    
    import "fmt"
    
    type ProductVisitor struct {
        products map[string]int
    }
    
    func NewProductVisitor() ISaleOrderVisitor {
        return &ProductVisitor{
            products: make(map[string]int,0),
        }
    }
    
    func (me *ProductVisitor) Visit(it *SaleOrder) {
        n,ok := me.products[it.Product]
        if ok {
            me.products[it.Product] = n + it.Quantity
        } else {
            me.products[it.Product] = it.Quantity
        }
    }
    
    func (me *ProductVisitor) Report() {
        for k,v := range me.products {
            fmt.Printf("product=%s, sum=%v
    ", k, v) } }

    방문 자 모드 소결
            
    (1)            ,            。
    (2)           ,           ,       。
    (3)          ,       。
    (4)       ,        。
    
            
    (1)        :             ,
                         ,
                          ,       。
    (2)        :        、       , 
                           ,
                   ,      。
    (3)        :    “    ”,
                           ,     。
        
    (       <>)

    (end)

    좋은 웹페이지 즐겨찾기