2016-10-30 2 views
2

그래서 저는 Go 프로그래밍 세계에 비교적 새로운 것이므로 지속성 레이어를 추상화하려고 시도 할 때 커뮤니티가 "모범 사례"라고 생각하는 것이 궁금합니다.GO에서 지속성 레이어 추상화 멀리

DDD에서 이것은 종종 일련의 동의를 응용 프로그램 계층에 표시하는 리포지토리를 통해 처리됩니다.

내 관심은 내가 객체 지향 디자인의 관점에서 이러한 문제를 과도하게 "조정"하여 다른 프로그래밍 패러다임을 탐구하고 싶다는 것이다.

이것은 마이크로 서비스 개발에 대한 나의 첫 번째 시도이기도합니다. 이것이 내가 디자인을 가능한 한 간단하게 유지하고자하는 이유 중 하나입니다.

답변

1

나는이 질문에 대해 한 가지 좋은 대답이 있다고 생각하지 않는다. 여러 접근법이 좋을 수도 있고, 특정 관점에서 더 나을 수도 있고, 또 다른 관점에서 더 나아질 수도있다.

DB 특정 동작 및 유형을 숨기는 인터페이스 (Go 인터페이스 유형의 의미가 아님)를 만들려고합니다. 그러면 다른 모든 부분이 제공되므로 나중에 새 db 구현으로 쉽게 전환 할 수있는 옵션이 남습니다. 코드는이 DB 인터페이스를 통해 영구 계층에 엄격하게 액세스합니다.

DB 인터페이스는 Go 모델 유형 (지속적 계층에 저장된 모델링 데이터)을 정의해야하며, 이러한 유형의 작업 (예 : 로드, 찾기, 저장. 당신이 Manager 인터페이스의 구현 (또는 여러 사람을) 만들 수 있습니다

package db 

type ID int64 

type User struct { 
    ID ID 
    Name string 
} 

// Manager contains the operations that involve the persistence layer. 
type Manager interface { 
    LoadUser(id ID) (*User, error) 
    SaveUser(u *User) error 
    FindUsersByName(name string) ([]*User, error) 
    Close() error 
} 

그리고 : 사용자를 모델링 예를 들어

. MongoDB의 사용을 구현 :

package mongo 

import (
    "db" 
    "gopkg.in/mgo.v2" 
) 

// manager is a db.Manager implementation that uses MongoDB 
type manager struct { 
    // unexported fields, e.g. MongoDB session: 
    sess *mgo.Sess 
} 

func (m *manager) LoadUser(id db.ID) (*db.User, error) { ... } 

func (m *manager) SaveUser(u *db.User) error { ... } 

func (m *manager) FindUsersByName(name string) ([]*db.User, error) { ... } 

func (m *manager) Close() error { 
    m.sess.Close() 
    return nil 
} 

func New(mongoURL string) (db.Manager, error) { 
    // Create, initialize your manager, and return it: 
    sess, err := mgo.Dial(url) 
    if err != nil { 
     return nil, err 
    } 
    return &manager{sess: sess}, nil 
} 

db.Manager 인스턴스 (그것이 (몽고) DB 서버에 대한 연결을 구축하는 것을 포함 이후) 가능한 오랫동안 (예를 들어 글로벌 인스턴스)를 유지해야한다. 사용량에 따라, 수명이 짧은 사용 (예 : HTTP 요청 제공)을 위해 사본 또는 복제본을 얻으려면 Manager.Copy()Manager.Clone() 작업을 지원해야합니다. 누군가가 어딘가에 db.Manager의 값을 취득 mongo.New() 전화를 가지고 있지만, 거기에서 우리는 단지 구현에 대한 DB의 구체적 세부 사항을 남겨두고 Manager 통해 영속 계층과 상호 작용할 수 있습니다

이 예제를 사용. 예를 들어

:

var mgr db.Manager 
var err error 

mgr, err = mongo.New("<mongodburl>") 
if err != nil { 
    log.Printf("Could not connect to db:", err) 
    return 
} 
defer mgr.Close() 

id := 123456 
u, err := mgr.LoadUser(id) 
if err != nil { 
    log.Printf("Failed to load user [id: %v]: %v\n", id, err) 
    return 
} 
fmt.Printf("Loaded User: %+v\n", u) 
+0

Isin't 그 패턴 저장소와 같은? – plalx

+0

@plalx 예,하지만 아무도 적용 할 수 없다거나 Go에서 사용하는 것이 적절하지 않다고 말한 사람은 없습니다. – icza

+1

"제가 우려하는 것은 객체 지향 설계의 관점에서 이러한 문제를 과도하게"조정 "하여 다른 프로그래밍 패러다임을 탐구하고 싶다는 것입니다. 바꾸어 말하면 OP는 저장소 패턴을 이미 알고 있지만 Go의 지속성 문제를 추상화하는 다른 좋은 대안을 찾고 있습니다. – plalx

관련 문제