英文:
golang separation of concerns vs usability
问题
我一直在努力保持go模块的整洁分离,避免循环依赖。
现在我有这样的代码:
package chain
type Block struct{
Content []byte
Number int
}
var Chain []Block = make([]Block, 10)
func AddBlockToChain(block Block){
// 进行一些检查
//...
// 添加到链上
Chain[block.Number] = block
}
func GetBlock(number int) Block {
// 进行一些检查
//...
// 从链上获取
return Chain[number]
}
为了实现共识,我需要一些额外的关于区块的信息。这些信息可能因使用的共识算法而异。我希望共识算法可以互换(例如通过启动时的标志)。
将信息作为区块的字段存储会很方便,这样当我调用GetBlock(3)或从其他地方获取一个区块时,不仅可以访问区块本身,还可以访问该区块当前所处的共识状态的信息。
另一方面,我希望将仅与特定共识算法相关的数据与基本区块数据分开存储,甚至可以放在一个单独的包中。
我应该如何设计我的程序?在哪里存储与特定共识算法相关的数据?
一些背景信息:
我正在尝试从头开始构建一个区块链应用程序。我有一个负责存储数据块的"chain"模块,以及一个负责在运行我的程序实例的多个节点之间创建共识的"consensus"模块。
英文:
I have always struggled keeping go modules neatly separated and avoiding cyclic dependencies.
Right now I have code like this:
package chain
type Block struct{
Content []byte
Number int
}
var Chain []Block = make([]Block, 10)
func AddBlockToChain(block Block){
// do some checks
//...
// add to chain
Chain[block.Number] = block
}
func GetBlock(number int) Block {
// do some checks
// ...
// get from chain
return Chain[number]
}
To achieve consensus I need some extra info on the block. The info may be different depending on which consensus algorithm I use. I want the consensus algorithm to be interchangeable (e.g. by flag on start up).
It would be convenient to store the info as fields in the block, so that when I call GetBlock(3) or get a block from anywhere else I can not only access the block but also the info on what state of consensus this block is in at the moment.
On the other hand I wanted to keep data that is only relevant for a certain consensus algorithm separate from basic block data - maybe even in a separate package.
How should I design my program? Where should I keep data relevant for a certain consensus algorithm?
Some background info:
I am trying to build a block chain application from scratch. I have a "chain" module responsible for storing blocks of data and a "consensus" module responsible for creating consensus between multiple peers running an instance of my program on what that data is.
答案1
得分: 3
consensus.Block
和chain.Block
是两种不同的类型,但由于你将chain.Block
嵌入到了consensus.Block
中,所以你可以从一个类型中访问另一个类型。
只需在AddBlockToChain()
中传递consensus.Block
:
func AddBlockToChain(block consensus.Block)
然后通过block.Block
来访问它。
示例代码:
package main
import "fmt"
type ChainBlock struct {
id int
}
type ConsensusBlock struct {
ChainBlock
idCons int
}
func printChainBlockId(consBlock ConsensusBlock) {
fmt.Println(consBlock.ChainBlock.id)
}
func main() {
test := ConsensusBlock{
ChainBlock: ChainBlock{
id: 42,
},
idCons: 44,
}
printChainBlockId(test)
}
请注意,我将admin
更改为test
,以使代码正确运行。
英文:
consensus.Block
and chain.Block
are two separate types but since you are embeddding chain.Block
in consensus.Block
, you can access one from another.
Just pass consensus.Block
in AddBlockToChain()
:
`func AddBlockToChain(block consensus.Block)`
and then access it by: block.Block
Example:
package main
import "fmt"
type ChainBlock struct {
id int
}
type ConsensusBlock struct {
ChainBlock
idCons int
}
func printChainBlockId(consBlock ConsensusBlock) {
fmt.Println(consBlock.ChainBlock.id)
}
func main() {
test := ConsensusBlock{
ChainBlock: ChainBlock{
id: 42,
},
idCons: 44,
}
printChainBlockId(admin)
}
答案2
得分: -1
为了完整起见,我想添加一个解决方案,将共识算法的代码和数据放在一个与区块和链码不同的包中:
在区块中添加一个额外的字段,如下所示:
Extra []byte
然后,在该算法包中,将共识算法所需的额外数据存储在一个结构体中,并将其编码为JSON或其他格式,以存储在额外字段中。
这种解决方案将不同的关注点分开。没有共识算法,链条就没有意义,但它们可能看起来非常不同,并且可能需要不同的数据。这样,不同的算法可以存储不同的数据。
然而,我没有选择这个解决方案,因为像 @syntagma 建议的那样,将所有代码放在一个包中似乎更简单。
英文:
For completeness I want to add a solution that keeps the code and data of the consensus algorithm in a different package than the block and chain code:
Add an extra field to the block like this:
Extra []byte
Then keep the extra data needed for a consensus algorithm in that algorithms package in a struct and encode it to json or some other format to store it in the extra field.
This solution keeps separate concerns separate. The chain would not make sense without a consensus algorithm, but they can look very different and might need different data. This way different algorithms can store different data.
I did not go with this solution however, because it just seemed simpler to keep all the code in one package as @syntagma suggested.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论