是否有可能将使用接口和继承的Java结构重写为惯用的Golang方式?
这不是超级复杂的Java代码,但它显示了类继承的强度,但我想尝试在Go中以某种方式实现相同的结果
Java代码:
首先是一个类接口。
public interface WebEntry {
String perform(ConnectionData connectionData, SessionData sessionData) throws Exception;
}
某处有一个网络条目列表WebEntry
:
List<WebEntry> webEntries = new ArrayList<>();
webEntries.add( new SavePasswordWebEntry() );
实现UserLoggedInWebEntry
WebEntry
public abstract class UserLoggedInWebEntry implements WebEntry {
@Override
public String perform(ConnectionData connectionData, SessionData sessionData) throws Exception {
// THIS IS THE LOGIC I DO NOT WANT TO DUPLICATE, HENCE ITS USING CLASS INHERITANCE
...
return userPerform(User user);
}
protected abstract String userPerform(User user) throws Exception;
}
通过使用类继承,我们可以创建一个仍然表现为UserLoggedInWebEntry
的{{1}},但每次我们想要“用户登录”时我们都不需要复制WebEntry
逻辑在网络条目“实例:
...
所以重点是,由于它使用类继承,开发人员只需实现public class SavePasswordWebEntry extends UserLoggedInWebEntry {
@Override
protected String userPerform(User user) throws Exception {
...
}
}
而不重复String userPerform(User user)
中...
的逻辑。
这是否有可能在Golang实现?如果是这样,它会是什么样子?
答案 0 :(得分:0)
我想出了如何自己实现同样的事情,即使我喜欢&#34; Just learn Go&#34;我得到的答案。
通过创建一个包含userLoggedInWebEntry
函数签名但仍返回WebEntryUserLoggedIn
函数签名的包装函数WebEntry
来解决此问题。
通过让开发人员只实现func( user User ) string
并且userLoggedInWebEntry
中的逻辑不重复
https://play.golang.org/p/adrk46YFIl8
package main
import (
"fmt"
)
type ConnectionData string
type SessionData string
type User string
type WebEntry func(connectionData ConnectionData, sessionData SessionData) string
type WebEntryUserLoggedIn func( user User ) string
func main() {
var webentries []WebEntry
webentries = append( webentries, userLoggedInWebEntry(SavePasswordWebEntry) )
// Test the invocation
fmt.Println( webentries[0]("ConnectionData", "SessionData") )
}
func userLoggedInWebEntry( webEntry WebEntryUserLoggedIn ) WebEntry {
return func(connectionData ConnectionData, sessionData SessionData) string {
// // THIS IS THE LOGIC I DO NOT WANT TO DUPLICATE, HENCE ITS USING CLASS INHERITANCE
var user User = "John"
return webEntry( user )
}
}
func SavePasswordWebEntry( user User ) string {
return fmt.Sprintf("user is %s", user )
}
答案 1 :(得分:-1)
也许是这样的?
type WebEntry interface {
Perform() string
}
type SomeWebEntry struct {
}
func (_ *SomeWebEntry) Perform() string {
return "SomeWebEntry"
}
type OtherWebEntry struct {
SomeWebEntry
}
func (this *OtherWebEntry) OtherPerform() string {
return this.Perform() + "OtherWebEntry"
}
func main() {
webEntries := []WebEntry{&SomeWebEntry{},&OtherWebEntry{}}
for _, v := range webEntries {
fmt.Println(v.Perform())
}
fmt.Println("-")
fmt.Println(webEntries[1].(*OtherWebEntry).OtherPerform())
}
您可以使用名为embedding的功能。
答案 2 :(得分:-1)
在这里你看。我不知道我是否理解正确。
package main
import (
"fmt"
)
type ConnectionData struct{}
type SessionData struct{}
type WebEntry interface {
Perform(c ConnectionData, s SessionData) (string, error)
}
type UserLoggedInWebEntry struct {
}
func (u *UserLoggedInWebEntry) Perform(c ConnectionData, s SessionData) (string, error) {
return u.UserPerform(c, s)
}
func (u *UserLoggedInWebEntry) UserPerform(c ConnectionData, s SessionData) (string, error) {
return "UserLoggedInWebEntry UserPerform", nil
}
type SavePasswordWebEntry struct {
UserLoggedInWebEntry
}
func (sp *SavePasswordWebEntry) Perform(c ConnectionData, s SessionData) (string, error) {
return "SavePasswordWebEntry Perform", nil
}
func main() {
webEntries := make([]WebEntry,0)
webEntries = append(webEntries, new(SavePasswordWebEntry))
for _, we := range webEntries {
fmt.Println(we.Perform(ConnectionData{},SessionData{}))
}
}