我在C++方面有比Go更多的经验。我试图理解如何在Go中惯用地表达Composite design pattern,特别是参考了属性。在C++中,我将使用父类来保存一组子类通用的属性和方法。我没有看到这在Go中如何工作。一个接口允许我定义要实现的方法,但它不允许我提供默认实现。我必须在实现接口的每个结构中重新实现该方法,并复制每个结构中的所有属性。我无法在接口中保留常用属性,因为接口没有数据元素。你如何在Go中进行这种重构?相当于子类的习语转到
这里的(在C++)什么,我想能在去做一个例子:
#include <string>
/*
* Parent class for edible things. Holds the "name" attribute.
*/
class Edible {
public:
Edible(const std::string &aName):
ed_Name(aName) { }
const std::string &name() const { return ed_Name; }
protected:
void setName(const std::string &aName) { ed_Name = aName; }
private:
std::string ed_Name;
};
/*
* Subclass of Edible for fruits. Depends on Edible to store the name.
*/
class Fruit: public Edible {
public:
Fruit(const std::string &aName,
const std::string &aPlant):
Edible(aName),
fr_Plant(aPlant) { }
const std::string &plant() const { return fr_Plant; }
protected:
void setPlant(const std::string &aPlant) { fr_Plant = aPlant; }
private:
std::string fr_Plant;
};
/*
* Subclass of Edible for meats. Depends on Edible to store the name.
* Has attributes for the animal and the cut of meat.
*/
class Meat: public Edible {
public:
Meat(const std::string &aName,
const std::string &aAnimal,
const std::string &aCut):
Edible(aName),
me_Animal(aAnimal),
me_Cut(aCut) { }
const std::string &animal() const { return me_Animal; }
const std::string &cut() const { return me_Cut; }
protected:
void setAnimal(const std::string &aAnimal) { me_Animal = aAnimal; }
void setCut(const std::string &aCut) { me_Cut = aCut; }
private:
std::string me_Animal;
std::string me_Cut;
};
Go没有继承,所以type层次通常是你想要避免的东西。 C++/Java设计模式不适合Go中使用的结构类型和组合。 – JimB
在Go中搜索嵌入,并阅读推荐的设计模式。正如JimB所说,你想重新考虑一下设计,从我来描述它的最简单的方式是继承关系是颠倒的。你永远不会继承,你只能撰写/嵌入。除此之外,当你使用父类型实现多态行为时,比如迭代'[] ParentType'并调用'MethodThatsOverriden()',你需要定义一个接口并使用它。 – evanmcdonnal