在Go语言中改进多态性和装饰器模式

huangapple go评论76阅读模式
英文:

Improving Polymorphism and Decorator pattern in Go

问题

我正在阅读一本设计模式的书,并尝试将这些模式应用到Go语言中,以此来学习两者。

目前我已经学到了装饰器模式,并遇到了一个我很好奇的情况。

以下是一些示例代码:

type Beverage interface {
	getDescription() string
	cost() float64
}

type HouseBlend struct{}

func (hb *HouseBlend) getDescription() string {
	return "House Blend Coffee"
}

func (hb *HouseBlend) cost() float64 {
	return .89
}

type Mocha struct {
	b Beverage
}

func (m *Mocha) getDescription() string {
	return m.b.getDescription() + ", Mocha"
}

func (m *Mocha) cost() float64 {
	return m.b.cost() + .20
}

下面的代码有什么区别:

var hb Beverage = &HouseBlend{}

// 这段代码可以工作,因为hb是一个接口类型
hb = &Mocha{
    b: hb,
}

hb := &HouseBlend{}

// 这段赋值会失败,因为Mocha不是HouseBlend类型
hb = &Mocha{
	b: hb,
}

下面的代码也可以工作

hb := *new(Beverage)

hb = &Espresso{}

hb = &Mocha{
	b: hb,
}

是否有一种简洁的方式给变量hb指定接口类型,或者必须明确指定才能将变量重新赋值为不同的类型来实现"装饰"结构体的功能?

欢迎提出任何改进装饰器模式和实现清晰多态性的建议。谢谢!

英文:

I'm working through a design patterns book and trying to apply the patterns to Go as a way to learn both.

Currently I have reached the decorator pattern and I ran into a scenario I was curious about.

Here is some sample code:

type Beverage interface {
	getDescription() string
	cost() float64
}

type HouseBlend struct{}

func (hb *HouseBlend) getDescription() string {
	return "House Blend Coffee"
}

func (hb *HouseBlend) cost() float64 {
	return .89
}

type Mocha struct {
	b Beverage
}

func (m *Mocha) getDescription() string {
	return m.b.getDescription() + ", Mocha"
}

func (m *Mocha) cost() float64 {
	return m.b.cost() + .20
}

What is the difference between

var hb Beverage = &HouseBlend{}

//This works since hb is an interface type
hb = &Mocha{
    b: hb,
}

And

hb := &HouseBlend{}

//This assignment fails since Mocha is not type HouseBlend
hb = &Mocha{
	b: hb,
}

This also works

hb := *new(Beverage)

	hb = &Espresso{}

	hb = &Mocha{
		b: hb,
	}

Is there a shorthand way of giving my variable hb the interface type or does it need to be explicit in order to be able to "decorate" my struct and reassign the variable to different types?

Any suggestions on improving the decorator pattern here and achieving clean polymorphism are welcome. Thank you!

答案1

得分: 0

var hb Beverage 是显式给变量指定类型的方式。隐式类型推断会根据你赋给变量的值来确定类型。关于“简写”的具体需求我不太清楚,因为 var name Type 已经相当简短了。但如果你真的想使用简短的变量声明,你可以使用类型转换:

hb := Beverage(&HouseBlend{})
英文:

var hb Beverage is how you explicitly give the variable a type. Implicit typing will always get the type of the value you put into it. I'm not sure what you're looking for in terms of "shorthand" here, as var name Type is already pretty short, but if you really want to use a short variable declaration you could use a type conversion:

hb := Beverage(&HouseBlend{})

答案2

得分: 0

你可以使用简写形式,并声明hb为一个使用接口的变量:

hb := Beverage(&HouseBlend{})

这段代码并不完全正确:

// 你分配了一个指向接口的指针,并将其重定向以获取一个未初始化的接口值
hb := *new(Beverage)

// 在这里,你丢弃了第一个赋值的值
hb = &Espresso{}
英文:

You can use the short form and declare hb as an interface using:

hb:=Beverage(&HouseBlend{})

This piece of code is not exactly correct:

// You allocate a pointer to an interface, and redirect it to get an uninitialized interface value
hb := *new(Beverage)

// Here, you throw away the value of the first assignment
hb = &Espresso{}

huangapple
  • 本文由 发表于 2022年8月31日 06:26:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/73549046.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定