Golang中如何创建struct的CollectionBootstrap

Golang中如何创建struct的CollectionBootstrap 大家好,

我正在阅读一篇关于软件架构与软件设计区别的文章https://codeburst.io/software-architecture-the-difference-between-architecture-and-design-7936abdd5830。顺便说一句,这篇文章很值得一读。回到正题,我看到一段代码挺有意思,觉得可以加入到我的项目中。这是一个工厂设计模式

PHP-Code

我觉得这是PHP代码。就是这样!我正尝试用Go语言复现它。

GOLANG

但我遇到了一个错误

Error-GOLANG

以下是我的代码。我在这里卡住了。如果有人用Go语言做过同样的事情,请帮帮我。非常感谢


更多关于Golang中如何创建struct的CollectionBootstrap的实战教程也可以访问 https://www.itying.com/category-94-b0.html

10 回复

你能教我一种完美的设计吗?

更多关于Golang中如何创建struct的CollectionBootstrap的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好,

你期望你的 Get 函数返回不同的模型对象吗?如果是,你将如何设置返回类型?

感谢你,Imatmati

上面的解决方案确实有效,但如果情况如此,为什么不直接声明模型呢?我处理这个问题的原因在于,当模型名称发生变更时,就不需要在整个代码中逐个查找模型声明。不过无论如何,还是感谢你分享解决方案。

感谢BB-8先生的强调

image

我会对这个问题进行更深入的研究。谢谢!

imatmati:

错误

尊敬的Ivan先生:

感谢您花费时间和精力回复我的帖子。非常感谢 🙂

不过,我想创建一个能够接收模型名称并返回其结构体/模型的函数,或许可以做成全局函数。您的建议很好,但举个例子,如果我实现一个接口,可能会导致模型声明的冗余。而第二种使用 interface{} 作为返回类型的方法,会导致特定模型的属性信息丢失。

你好,

能帮我审阅几个要点吗?你的Get方法返回了一个DataFactory。我猜你是在尝试实现抽象工厂模式而不是普通工厂模式。如果是这样,为什么你要返回User?这不符合工厂模式的设计理念。如果你想从Get方法返回多个可能的对象,这些对象应该实现某个接口,或者以interface{}类型返回。你出现的错误是因为试图将User对象赋值给DataFactory结构体……其实你可以直接返回&models.User{}。但你的设计仍然存在缺陷。

我的解决方案假设您已知类型,但如果您使用接口,就可以采用不同的实现方式,且无需进行类型转换。虽然我也提到了这种方案,但只给出了返回interface{}情况的实现。这有什么实际意义?通过这种方式,您可以隐藏用户初始化的具体细节,甚至能够根据参数选择不同的初始化方法。

不过关于您最初的实现,仍有一个问题困扰着我:您期望如何将User对象作为DataFactory返回?两者之间并无关联,而多态性仅能通过接口实现。

如果我正确理解了您的想法,您的Get函数应该返回不同的模型对象,就像PHP示例中那样。在这种情况下,除了我解释过的两种方案(接口或interface{}后进行类型转换)之外,我没有看到其他解决方案。我考虑的是类似这样的实现:

package main

type User struct {}
type Purchase struct {}
type DefaultType struct {}

func Get(_type string) interface{} {
 switch _type {
	case "user":
		return &User{}
	case "purchase":
		return &Purchase{}
	default:
		return &DefaultType{}
  }
}


func main() {
    var user User = Get("user").(User)
}

以下是我的代码。我在这里有点卡住了。如果有人用Golang做过同样的事情,请帮帮我。非常感谢

为了快速说明你遇到错误的原因:

在switch语句的User分支中,你有这行代码:

DataFactory = models.User{}

你之前将DataFactory定义为一个类型,现在你试图将models.User{}的值赋给类型DataFactory,这当然不会起作用。

你可以简单地创建一个新变量,并将model.User{}的值赋给它。

case "User":
    factory := models.User{}
    return &factory

希望这对你有帮助。

在Go语言中,要实现类似PHP中的CollectionBootstrap工厂模式,你需要定义一个结构体集合,并通过工厂方法来创建和初始化这些结构体。以下是一个完整的示例,展示如何实现这个模式:

package main

import (
    "fmt"
)

// 定义基础结构体接口
type Entity interface {
    GetName() string
}

// 具体结构体实现
type User struct {
    Name string
}

func (u *User) GetName() string {
    return u.Name
}

type Product struct {
    Name string
}

func (p *Product) GetName() string {
    return p.Name
}

// CollectionBootstrap 工厂
type CollectionBootstrap struct {
    entities []Entity
}

// NewCollectionBootstrap 工厂方法
func NewCollectionBootstrap() *CollectionBootstrap {
    return &CollectionBootstrap{
        entities: make([]Entity, 0),
    }
}

// AddEntity 添加实体到集合
func (cb *CollectionBootstrap) AddEntity(entity Entity) {
    cb.entities = append(cb.entities, entity)
}

// GetEntities 获取所有实体
func (cb *CollectionBootstrap) GetEntities() []Entity {
    return cb.entities
}

// CreateFromArray 从数组创建集合(类似PHP的工厂方法)
func CreateFromArray(data []map[string]string) *CollectionBootstrap {
    collection := NewCollectionBootstrap()
    
    for _, item := range data {
        if name, exists := item["type"]; exists {
            switch name {
            case "user":
                if userName, ok := item["name"]; ok {
                    collection.AddEntity(&User{Name: userName})
                }
            case "product":
                if productName, ok := item["name"]; ok {
                    collection.AddEntity(&Product{Name: productName})
                }
            }
        }
    }
    
    return collection
}

func main() {
    // 测试数据
    data := []map[string]string{
        {"type": "user", "name": "John Doe"},
        {"type": "product", "name": "Laptop"},
        {"type": "user", "name": "Jane Smith"},
    }
    
    // 使用工厂方法创建集合
    collection := CreateFromArray(data)
    
    // 遍历并输出结果
    for _, entity := range collection.GetEntities() {
        fmt.Printf("Type: %T, Name: %s\n", entity, entity.GetName())
    }
}

运行结果:

Type: *main.User, Name: John Doe
Type: *main.Product, Name: Laptop
Type: *main.User, Name: Jane Smith

这个实现包含了以下关键部分:

  1. Entity接口:定义了所有结构体必须实现的方法
  2. 具体结构体:User和Product实现了Entity接口
  3. CollectionBootstrap:管理结构体集合的容器
  4. 工厂方法:CreateFromArray根据输入数据创建相应的结构体实例

如果你需要处理不同类型的数据,可以扩展switch语句来支持更多的结构体类型。这种模式在需要根据运行时数据动态创建不同对象类型的场景中非常有用。

回到顶部