NOTE

6.14 简单工厂

把类的创建和使用分离开 1. Java 1.1. client 1.2. 产品 1.3. 工厂 2. Golang 2.1. 产品 2.2. 工厂 2.3. client 3. 实例 模板方法+简单工厂+策略模式 ! 20200913121959997 27705.png - pb.go - abstract template.go - content re

Software Architecture & Engineering约 1 分钟读完historical

这是历史学习笔记,可能存在过时或不完整的理解。

把类的创建和使用分离开

1. Java

1.1. client

public class Client
{
    public static void main(String[] args)
    {
        Car car = CarFactory.getCart("奥迪");
    }
}

1.2. 产品

public interface Car
{
}
public class AudiCar implements Car
{
}
public class QQCar implements Car
{
}

1.3. 工厂

public class CarFactory
{
    public static Car getCart(String name)
    {
        //问题在于这里太多if else
        if("奥迪".equals(name))
            return new AudiCar();
        else if ("QQ".equals(name))
            return new QQCar();
        else
            throw new RuntimeException("没有该car");
    }

}

2. Golang

2.1. 产品

/*汽车接口*/
type Car interface {
	Run()
}

//QQ车
type QQCar struct {

}

func (Q QQCar) Run() {
	fmt.Println("I am QQ car")
}

//奥迪车
type AodiCar struct {

}

func (Q AodiCar) Run() {
	fmt.Println("I am Aodi car")
}

2.2. 工厂


/*简单工厂就是构造函数*/
func NewCar(name string) Car {
	if name == "QQ" {
		return &QQCar{}
	} else if name == "Aodi" {
		return &AodiCar{}
	} else {
		return nil
	}
}

2.3. client

func main() {
	qqCar := 简单工厂.NewCar("QQ")
	aodiCar := 简单工厂.NewCar("Aodi")
	qqCar.Run()
	aodiCar.Run()
}

3. 实例

模板方法+简单工厂+策略模式

  • pb.go
package pb

type Request struct {

}

type Response struct {

}
  • abstract_template.go
package template

import (
	"context"
	"fmt"
	"example/template/pb"
)

/*实现了IFetchDataService*/
type abstractFetchDataService struct {
	IFetchDataSteps //内部的处理步骤
	req             *pb.Request
	rsp             *pb.Response
	basicInfo       interface{} //基础数据
	extraInfo       interface{} //额外数据
}

func (t *abstractFetchDataService) checkParam(ctx context.Context) error {
	fmt.Println("default checkParam")
	return nil
}

func (t *abstractFetchDataService) getBasicInfo(ctx context.Context) error {
	fmt.Println("default getBasicInfo")
	return nil

}

func (t *abstractFetchDataService) getExtraInfo(ctx context.Context) error {
	fmt.Println("default getExtraInfo")
	return nil

}

//newTemplate
func newTemplate(iSteps IFetchDataSteps) *abstractFetchDataService {
	return &abstractFetchDataService{IFetchDataSteps: iSteps}
}

/*模板方法固定的步骤*/
func (t *abstractFetchDataService) HandleRequest(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
	t.req = req
	t.rsp = rsp
	if err := t.IFetchDataSteps.checkParam(ctx); err != nil {
		return err
	}
	if err := t.IFetchDataSteps.getBasicInfo(ctx); err != nil {
		return err
	}
	if err := t.IFetchDataSteps.getExtraInfo(ctx); err != nil {
		return err
	}
	return nil
}
  • source_a_template_impl.go
package template

import (
	"context"
	"fmt"
)

const TypeSourceAService = 2

var sourceAServiceConstructorFunc fetchDataServiceConstructor = func() IFetchDataService {
	return NewFetchDataFromSourceAService()
}

func init() {
	GlobalServiceFactory.RegisterService(TypeSourceAService, sourceAServiceConstructorFunc)
}

/*source_a 服务*/
type FetchDataFromSourceAService struct {
	*abstractFetchDataService
}

func (f *FetchDataFromSourceAService) checkParam(ctx context.Context) error {
	fmt.Println("checkParam")
	return f.abstractFetchDataService.checkParam(ctx)
}

func (f *FetchDataFromSourceAService) getBasicInfo(ctx context.Context) error {
	fmt.Println("getBasicInfo")
	return f.abstractFetchDataService.getBasicInfo(ctx)

}

//func (f *FetchDataFromSourceAService) getExtraInfo(ctx context.Context) error {
//	fmt.Println("getExtraInfo")
//	return f.abstractFetchDataService.getExtraInfo(ctx)
//
//}


//NewFetchDataFromSourceAService
func NewFetchDataFromSourceAService() *FetchDataFromSourceAService {
	service := &FetchDataFromSourceAService{}
	service.abstractFetchDataService = newTemplate(service)
	return service
}
  • factory.go
package template

import "fmt"

var GlobalServiceFactory = newServiceFactory()

//自定义func。用于创建service实例
type fetchDataServiceConstructor = func() IFetchDataService

//serviceFunc工厂
type serviceFactory struct {
	serviceMap map[int]fetchDataServiceConstructor
}

//newServiceFactory
func newServiceFactory() *serviceFactory {
	return &serviceFactory{serviceMap: make(map[int]fetchDataServiceConstructor)}
}

//根据service type获取service
func (s *serviceFactory) GetServiceByType(serviceType int) (IFetchDataService, error) {
	serviceConstructor, ok := s.serviceMap[serviceType]
	if ok {
		return serviceConstructor(), nil
	}
	err := fmt.Errorf("GetServiceByType: serviceType %v invalid", serviceType)
	return nil, err
}

//注册serviceType和serviceConstructor
func (s *serviceFactory) RegisterService(serviceType int, serviceConstructor fetchDataServiceConstructor) {
	s.serviceMap[serviceType] = serviceConstructor
}
  • itemplate.go
package template

import (
	"context"
	"example/template/pb"
)

/*对外提供获取数据列表的接口*/
type IFetchDataService interface {
	HandleRequest(ctx context.Context, req *pb.Request, rsp *pb.Response) error
}

/*内部的处理步骤*/
type IFetchDataSteps interface {
	//检查参数
	checkParam(ctx context.Context) error
	//获取基础数据
	getBasicInfo(ctx context.Context) error
	//获取额外数据
	getExtraInfo(ctx context.Context) error
}
  • template_test.go
package template

import (
	"context"
	"testing"
)

func TestTemplate(t *testing.T) {
	service, _ := GlobalServiceFactory.GetServiceByType(TypeSourceAService)
	service.HandleRequest(context.Background(), nil, nil)
}
//输出
checkParam
default checkParam
getBasicInfo
default getBasicInfo
default getExtraInfo

讨论

使用 GitHub 账号参与讨论,评论会保存在 GitHub Issues 中。在 GitHub 查看