抽象工厂-Go

抽象工厂——工厂的工厂

工厂方法将一族相关对象分组在一起,如果我们将对象族按更结构化的层次分组会怎样?

描述

抽象工厂设计模式是一个新的分组层,用于实现更大更复杂的组合对象,该对象通过接口使用。对族中的对象分组和对族进行分组的想法是要拥有可以互换且更容易成长的大型工厂。开发的早期阶段,与工厂和抽象工厂合作要比等到所有具体实现都完成再启动代码要容易的多。另外,除非我们知道在特定领域的库存将非常大并且很容易的分为几类,否则不会编写抽象工厂。

目标

当对象数量增长到足以创建一个唯一的点来获取所有对象时,对相关产品族对象进行分组是非常方便的,这是获得运行时对象创建灵活性的唯一方法。

  • 为工厂方法提供新的封装层,以返回所有工厂的公共接口
  • 将普通工厂分组为超级工厂(工厂的工厂)

例子

再以整车制造为例,我们需要重用在建造者模式中实现的工厂。我们希望展示使用不同方法来解决同一问题的相似性,以便看到每一种方法的优缺点。中间会展示Go的隐式接口功能,因为我们不需要接触任何东西,最后将创建一个新的工厂来创建装运订单。

首先是整车工厂(抽象工厂),该接口定义了一个具有Build方法(输入值为工厂类型,返回值为Vehicle,也是一个接口,所有车辆都应实现该接口,和一个错误信息)的工厂,所有具体工厂应实现该接口。

type VehicleFactory interface {
	Build(v int) (Vehicle, error)
}

其次是BuildFactory方法,输入一个工厂类型,输出值为具体工厂和错误信息。该方法根据输入的类型信息,产生对应的工厂。

const (
	CarFactoryType       = 1
	MotorbikeFactoryType = 2
)

func BuildFactory(f int) (VehicleFactory, error) {
	switch f {
	case CarFactoryType:
		return new(CarFactory), nil
	case MotorbikeFactoryType:
		return new(MotorbikeFactory), nil
	default:
		return nil, errors.New(fmt.Sprintf("Factory with id %d not recognized\n", f))
	}
}

具体工厂的定义如下:

const (
	LuxuryCarType = 1
	FamilyCarType = 2
)

type CarFactory struct{}

func (c *CarFactory) Build(v int) (Vehicle, error) {
	switch v {
	case LuxuryCarType:
		return new(LuxuryCar), nil
	case FamilyCarType:
		return new(FamilyCar), nil
	default:
		return nil, errors.New(fmt.Sprintf("Vehicle of type %d not recognized\n", v))
	}
}

具体工厂中接受一个具体车辆的类型,返回对应的车辆实例。

测试

func TestCarFactory(t *testing.T) {
	carF, err := BuildFactory(CarFactoryType)
	if err != nil {
		t.Fatal(err)
	}

	carVehicle, err := carF.Build(LuxuryCarType)
	if err != nil {
		t.Fatal(err)
	}

	t.Logf("Car vehicle has %d seats\n", carVehicle.NumWheels())

	luxuryCar, ok := carVehicle.(Car)
	if !ok {
		t.Fatal("Struct assertion has failed")
	}
	t.Logf("Luxury var has %d doors.\n", luxuryCar.NumDoors())
}

测试代码中首先根据BuildFactory方法获取对应的工厂方法,检查是否出错,再根据对应的工厂方法产出对应的car,再访问Vehicle接口的NumWheels方法获取具体信息,根据类型断言luxuryCar, ok := carVehicle.(Car)确定该类型是不是所期待的具体类型,最后访问具体类型的与接口不同的方法,确定luxuryCar的门有4个。

完整代码见 https://github.com/ricardoliu404/go-design-patterns/tree/master/creational/abstract_factory

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值