英文:
Tier abstraction of data in Go
问题
我将为您翻译以下内容:
我打算在Go中创建一个项目,但我希望将我的层进行分离。我的目标是创建一个类似DAO模式的代码包,即我希望我的调用者只能与服务的接口进行通信(可能是另一个项目),而不是与具体实现进行通信。这样可以避免将来更改数据库时,调用者不需要更改,并且对此更改应该是透明的。
我考虑创建一个名为"db"的项目,其中包含一个名为"persistence"的文件和一个名为"persistence"的包。
package persistence
// 需要从服务(另一个项目)中使用的CRUD接口
type Recorder interface {
SelectKey([]byte) error
Insert([]byte, []byte) error
Update([]byte, []byte) error
Delete([]byte) error
}
// Oracle的结构体
type ManageDataOracle struct {
}
// 二叉树的结构体
type ManageDataBinaryTree struct {
}
// MongoDB的结构体
type ManageDataMongoDb struct {
}
// Oracle的实现
func (memory *ManageDataOracle) SelectKey(pKey []byte) error {
// Oracle的逻辑在这里
return nil
}
func (memory *ManageDataOracle) Insert(pKey []byte, pValue []byte) error {
// Oracle的逻辑在这里
return nil
}
func (memory *ManageDataOracle) Update(pKey []byte, pValue []byte) error {
// Oracle的逻辑在这里
return nil
}
func (memory *ManageDataOracle) Delete(pKey []byte) error {
// Oracle的逻辑在这里
return nil
}
// 二叉树的实现
func (memory *ManageDataBinaryTree) SelectKey(pKey []byte) error {
// 二叉树的逻辑在这里
return nil
}
func (memory *ManageDataBinaryTree) Insert(pKey []byte, pValue []byte) error {
// 二叉树的逻辑在这里
return nil
}
func (memory *ManageDataBinaryTree) Update(pKey []byte, pValue []byte) error {
// 二叉树的逻辑在这里
return nil
}
func (memory *ManageDataBinaryTree) Delete(pKey []byte) error {
// 二叉树的逻辑在这里
return nil
}
// MongoDB的实现
func (memory *ManageDataMongoDb) SelectKey(pKey []byte) error {
// MongoDB的逻辑在这里
return nil
}
func (memory *ManageDataMongoDb) Insert(pKey []byte, pValue []byte) error {
// MongoDB的逻辑在这里
return nil
}
func (memory *ManageDataMongoDb) Update(pKey []byte, pValue []byte) error {
// MongoDB的逻辑在这里
return nil
}
func (memory *ManageDataMongoDb) Delete(pKey []byte) error {
// MongoDB的逻辑在这里
return nil
}
对于如何进行概念分离或如何从另一个项目中调用上述代码,您有什么建议吗?
英文:
I am going to create a project in Go, but I want to separate my tiers. My goal is create a package that has code something like the DAO pattern, i.e. I wish that my caller should only communicate with the interface of the service (which might be another project) and not with the implementation. This is to avoid the situation of a future change to the database, the caller should not change and should be transparent to this change.
I was thinking of creating a project db that contains a file called persistence with a package persistence as well
http://play.golang.org/p/O9b93F4LJp
package persistence
// Interface that have the CRUD which I need to use from service(another project)
type Recorder interface {
Selectkey([]byte) (err error)
Insert([]byte, []byte) (err error)
Update([]byte, []byte) (err error)
Delete([]byte) (err error)
}
// Struct for Oracle
type ManageDataOracle struct {
}
// Struct for binaryTree
type ManageDataBInaryTree struct {
}
// Struct for MongoDB
type ManageDataMongoDb struct {
}
// Implemtations for Oracle
func (memory *ManageDataOracle) SelectKey(pKey []byte) error {
// Logic for Oracle Here
return nil
}
func (memory *ManageDataOracle) Insert(pKey []byte, pValue []byte) error {
// Logic for Oracle Here
return nil
}
func (memory *ManageDataOracle) Update(pKey []byte, pValue []byte) error {
// Logic for Oracle Here
return nil
}
func (memory *ManageDataOracle) Delete(pKey []byte) error {
// Logic for Oracle Here
return nil
}
// Implemtations for Binary Tree
func (memory *ManageDataBInaryTree) SelectKey(pKey []byte) error {
// Logic for Binary tree Here
return nil
}
func (memory *ManageDataBInaryTree) Insert(pKey []byte, pValue []byte) error {
// Logic for Binary tree Here
return nil
}
func (memory *ManageDataBInaryTree) Update(pKey []byte, pValue []byte) error {
// Logic for Binary tree Here
return nil
}
func (memory *ManageDataBInaryTree) Delete(pKey []byte) error {
// Logic for Binary tree Here
return nil
}
// Implemtations for Mongo DB
func (memory *ManageDataMongoDb) SelectKey(pKey []byte) error {
// Logic for MongoDB Here
return nil
}
func (memory *ManageDataMongoDb) Insert(pKey []byte, pValue []byte) error {
// Logic for MongoDB Here
return nil
}
func (memory *ManageDataMongoDb) Update(pKey []byte, pValue []byte) error {
// Logic for MongoDB Here
return nil
}
func (memory *ManageDataMongoDb) Delete(pKey []byte) error {
// Logic for MongoDB Here
return nil
}
Any advice on how to do this separation of concepts, or how the previous code should be called from another project?
答案1
得分: 0
你正在走在正确的道路上,但是不同的持久化机制将使用不同的键类型(例如,在Oracle中使用整数,在Mongo中使用类似字符串的标识符)。
将数据序列化为[]byte
应该由抽象层处理,因为不同的底层持久化引擎将使用不同的数据表示形式。例如,考虑一个整数及其字节顺序。
因此,我建议将接口的签名更改为以下形式:
type Recorder interface {
SelectByKey(interface{}) error
DeleteByKey(interface{}) error
Insert(interface{}, interface{}) error
Update(interface{}, interface{}) error
}
这样,如果给定的键不是特定实现所需的正确类型,你还可以在SelectByKey
等方法中使用panic
。如果事先对键进行序列化,这将是不可能的,并且会导致问题。
英文:
You are on the right track but different persistence mechanisms will use different key types (for example an integer in an oracle and a string-like identifier in mongo).
The serialization of your data into []byte
should be handled by the abstraction layer because different underlying persistence engines will use different representations of your data. Consider for instance an integer and it's endianness.
Hence I would change the signatures of your interface to the following:
type Recorder interface {
SelectByKey(interface{}) error
DeleteByKey(interface{}) error
Insert(interface{}, interface{}) error
Update(interface{}, interface{}) error
}
this way you can also panic
inside, say SelectKey
if the given key is not of the correct type for a specific implementation. This wouldn't be possible if you serialized your key beforehand and would lead to trouble.
答案2
得分: 0
我认为你需要类似这样的东西:
https://github.com/qiangxue/golang-restful-starter-kit
这个起始套件旨在为你提供一个在Go中开发RESTful服务的最佳项目结构。该套件遵循SOLID原则,鼓励编写清晰和惯用的Go代码的最佳实践。
该套件提供了以下功能:
- 符合广泛接受的标准CRUD格式的RESTful端点
- 基于JWT的身份验证
- 通过环境变量和配置文件进行应用程序配置
- 带有上下文信息的结构化日志记录
- Panic处理和正确的错误响应生成
- 自动处理数据库事务
- 数据验证
- 完整的测试覆盖
英文:
I think you need something like this:
https://github.com/qiangxue/golang-restful-starter-kit
> This starter kit is designed to get you up and running with a project
> structure optimal for developing RESTful services in Go. The kit
> promotes the best practices that follow the SOLID principles and
> encourage writing clear and idiomatic Go code.
>
> The kit provides the following features right out of the box
>
> RESTful endpoints in the widely accepted format Standard CRUD
> operations of a database table JWT-based authentication Application
> configuration via environment variable and configuration file
> Structured logging with contextual information Panic handling and
> proper error response generation Automatic DB transaction handling
> Data validation Full test coverage
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论