了解 golang 中的继承与组合

Understanding Inheritance vs Composition in golang

来自Java背景,我无法理解如何使用组合实现继承或组合如何解决继承实现的一些常见解决方案?

interface ICommand {
    void Save(Records data)
    Records LoadRecords()
    Info GetInfo()
}

abstract class BaseCommand : ICommand {
    Records LoadRecords()  {
        var info = GetInfo()
        //implement common method.
    }
}

class CommandABC : BaseCommand {
    Info GetInfo(){
        return info;
    }

    void Save(Records data){
        // implement
    }
}

c = new CommandABC();
c.LoadRecords(); // BaseCommand.LoadRecords -> CommandABC.Info -> Return records
c.Save(); //Command ABC.Save

我想在 Go 中使用组合实现相同的功能。 毕竟这是一个公平的设计,应该很好地在 Go 中实现。

type ICommand interface {
    void Save(data Records)
    LoadRecords() Records
    GetInfo() Info
}

type BaseCommand struct {
    ICommand  //no explicit inheritance. Using composition
}

func(c BaseCommand) LoadRecords() {
    info := c.GetInfo()
    //implement common method
}

type CommandABC struct {
    BaseCommand //Composition is bad choice here?
}

func(c CommandABC) Save(data Records) {
    //implement
}

func(c CommandABC) GetInfo() Info {
    //implement
}

func main(){
    c := CommandABC{}
    c.LoadRecords(); // BaseCommand.LoadRecords -> fails to call GetInfo since ICommand is nil
    c.Save(); //Command ABC.Save
}

可以这样算

func main(){
    c := CommandABC{}
    c.ICommand = c //so akward. don't even understand why I am doing this
    c.LoadRecords(); // BaseCommand.LoadRecords -> fails to call GetInfo since ICommand is nil
    c.Save(); //Command ABC.Save
}

任何人都可以从 Go 设计的角度启发我实现这样的功能。

我的 concerns/queries 更多的是理解,如何使用组合实现这种 problems/code 可重用性以及更好的设计模式。

您可以通过几种不同的方式来实现,但最惯用的方式可能就是这些方式。很难根据一个没有细节且省略了大部分代码的人为示例给出详细答案,但我认为这可以到达您想要去的地方。

type Infoer interface {
    Info GetInfo()
}

func LoadRecords(i Infoer) Records  {
    var info = i.GetInfo()
    //implement common method.
}

type CommandABC struct {
    info Info
}

func (c CommandABC) GetInfo() Info {
    return c.info;
}

func (CommandABC) Save(data Records){
    // implement
}

c := CommandABC{};
records := LoadRecords(c);
c.Save(records);