Inheritance golang关注点与可用性的分离

Inheritance golang关注点与可用性的分离,inheritance,go,module,architecture,structure,Inheritance,Go,Module,Architecture,Structure,我一直在努力保持go模块整齐地分开,避免循环依赖 现在我有这样的代码: 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[bl

我一直在努力保持go模块整齐地分开,避免循环依赖

现在我有这样的代码:

    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]
}
Extra []byte
为了达成共识,我需要一些关于街区的额外信息。根据我使用的共识算法,信息可能会有所不同。我希望共识算法是可互换的(例如,通过启动时的标志)

将信息存储为块中的字段会很方便,这样,当我调用GetBlock(3)或从其他任何地方获取块时,我不仅可以访问块,还可以访问该块当前处于何种一致状态的信息

另一方面,我希望将仅与某个一致性算法相关的数据与基本块数据分开,甚至可能在单独的包中

我应该如何设计我的程序?我应该在哪里保存与某个共识算法相关的数据?

一些背景信息:


我正在尝试从头构建一个区块链应用程序。我有一个“链”模块负责存储数据块,还有一个“共识”模块负责在运行我的程序实例的多个对等方之间就数据是什么建立共识

consensess.Block
chain.Block
是两种不同的类型,但由于您将
chain.Block
嵌入
consensess.Block
,因此您可以从另一种类型进行访问

只需在
AddBlockToChain()
中传递
consensum.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(admin)
}

consensus.Block
chain.Block
是两种不同的类型,但由于您将
chain.Block
嵌入到
consensus.Block
中,因此您可以从另一种类型进行访问

只需在
AddBlockToChain()
中传递
consensum.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(admin)
}

为了完整性,我想添加一个解决方案,将一致性算法的代码和数据保存在不同于块和链代码的包中:

向块中添加一个额外字段,如下所示:

    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]
}
Extra []byte
然后将共识算法所需的额外数据保存在该算法包的结构中,并将其编码为json或其他格式,以将其存储在额外字段中

此解决方案将关注点分开。如果没有一致性算法,该链就没有意义,但它们看起来可能非常不同,可能需要不同的数据。这样,不同的算法可以存储不同的数据


但是,我没有采用这种解决方案,因为按照@syntagma的建议,将所有代码保存在一个包中似乎更简单。

为了完整性,我想添加一种解决方案,将一致性算法的代码和数据保存在不同于块和链代码的包中:

向块中添加一个额外字段,如下所示:

    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]
}
Extra []byte
然后将共识算法所需的额外数据保存在该算法包的结构中,并将其编码为json或其他格式,以将其存储在额外字段中

此解决方案将关注点分开。如果没有一致性算法,该链就没有意义,但它们看起来可能非常不同,可能需要不同的数据。这样,不同的算法可以存储不同的数据


但是,我没有采用这种解决方案,因为正如@syntagma所建议的那样,将所有代码保存在一个包中似乎更简单。

您正在混合来自不同包的不同类型:来自一个包的
块与来自另一个包的
块完全无关:您必须决定是要一个chain.Block链还是consensus.Block链。你不能在它们之间神奇地转换。在Java中我可以。我可以有一个包含子类实例的超类数组。当我想访问子类的方法时,我可以将数组中的对象转换为子类的对象,并访问子类的方法/字段。在go中,如果不像ΔλЛ的回答那样将两个结构放在同一个模块中,可能无法做到这一点。鉴于go中没有超/子类关系,很明显基于超-子类行为的解决方案无法工作。最后,对我来说,这是关于关注点的分离。我想我可以用模块和结构嵌入来解决这个问题。不过,我对任何其他解决方案都持开放态度。如果你想在围棋中实现互换性,请使用接口。嵌入只提供组合,而不提供多态性。您正在混合来自不同包的不同类型:来自一个包的
与来自另一个包的块完全无关:您必须决定是要一个chain.Block链还是consensus.Block链。你不能在它们之间神奇地转换。在Java中我可以。我可以有一个包含子类实例的超类数组。当我想访问子类的方法时,我可以将数组中的对象转换为子类的对象,并访问子类的方法/字段。在go中,如果不像ΔλЛ的回答那样将两个结构放在同一个模块中,可能无法做到这一点。鉴于go中没有超/子类关系,很明显基于超-子类行为的解决方案无法工作。最后,对我来说,这是关于关注点的分离。我想我可以用模块和结构嵌入来解决这个问题。不过,我对任何其他解决方案都持开放态度。如果你想在围棋中实现互换性,请使用接口。嵌入只提供组合,而不提供多态性。这样两个结构就不能在单独的模块中。我的假设是错误的,一个程序的一部分,应该是完全可互换的,应该是一个单独的模块吗?我认为在这种情况下,假设是错误的-我会在同一个包中创建两个文件(chain.go,consensus.go)。谢谢,这绝对是一个可行的方法。From:“http包包含17个go源文件(不包括UDI