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
这是历史学习笔记,可能存在过时或不完整的理解。
把类的创建和使用分离开
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 查看