Понимание наследования и состава в golang - PullRequest
0 голосов
/ 07 апреля 2020

Исходя из Java фона, я не могу понять, как наследование может быть достигнуто с помощью Composition или Как композиция решает некоторые из общих решений, достигнутых Inheritance?

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.

Мои опасения / вопросы больше связаны с пониманием того, как использовать композицию для таких проблем / повторного использования кода с улучшением шаблонов проектирования в будущем.

1 Ответ

2 голосов
/ 07 апреля 2020

Вы могли бы сделать это несколькими разными способами, но наиболее идиоматизм c, вероятно, что-то в этом роде. Трудно дать подробный ответ на основе надуманного примера без каких-либо подробностей и большей части кода, но я думаю, что это приводит к тому, что вы пытаетесь go.

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);
...