简单工厂
在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
优点
1.工厂类含有必要的判断逻辑,可以根据参数决定创建具体对象而外部无需关注细节
2.客户端无需记住类名,只需要记住对应参数即可
缺点
1.工厂类中集中了所有的逻辑,一旦不能正常工作则整个系统都要受到影响。
2.系统扩展困难,一旦添加新产品就不得不修改工厂逻辑
3.工厂角色无法形成基于继承的等级结构
代码实现
package simplefactory
type API interface {
Say(name string) string
}
type hiAPI struct{}
//Say hi to name
func (*hiAPI) Say(name string) string {
return fmt.Sprintf("Hi, %s", name)
}
//HelloAPI is another API implement
type helloAPI struct{}
//Say hello to name
func (*helloAPI) Say(name string) string {
return fmt.Sprintf("Hello, %s", name)
}
func NewApi(type int) API {
if type == 1 {
return &helloAPI{}
} else if type == 2 {
return &hiAPI{}
}
return nil
}
工厂模式
工厂模式解决了简单工厂用一个按钮工厂来解决所有产品创建的问题,而是将所有具体的创建交给具体的子工厂,从而更符合了设计模式的开闭原则。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。
优点
1.工厂创建客户无需关注创建细节
2.被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类,工厂可以自主确定创建何种产品对象
3.加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了,符合开闭原则
缺点
1.在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加。
2.具体工厂具有唯一性。
package factory
import "fmt"
//Operator 产品类接口
type Operator interface {
Op()
}
//OperatorFactory 是工厂接口
type OperatorFactory interface {
Create() Operator
}
//OperatorBase 是Operator 接口实现的基类,封装公用方法
type BaseOperator struct {
}
func (o *OperatorBase) Op() {
}
//PlusOperatorFactory 是 PlusOperator 的工厂类
type PlusOperatorFactory struct{}
func (PlusOperatorFactory) Create() Operator {
return &PlusOperator{
OperatorBase: &OperatorBase{},
}
}
//PlusOperator Operator 的实际加法实现
type PlusOperator struct {
*OperatorBase
}
//Op函数
func (o PlusOperator) Op() {
fmt.Println("Base")
}
抽象工厂
抽象工厂模式是所有形式的工厂模式中最为抽象和最具一般性的一种形态。它与工厂模式的区别在于工厂方法模式针对的是一个产品等级结构,而抽象工厂模式则需要面对多个产品等级结构。用于生成产品族的工厂,所生成的对象是有关联的
优点
1.抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建
2.增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”
缺点
1.在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合
2.增加新的工厂和产品族容易,增加新的产品等级结构麻烦
package abstractfactory
import "fmt"
//Main产品接口
type OrderMainDAO interface {
SaveOrderMain()
}
//Detail产品接口
type OrderDetailDAO interface {
SaveOrderDetail()
}
//抽象模式工厂接口
type DAOFactory interface {
CreateOrderMainDAO() OrderMainDAO
CreateOrderDetailDAO() OrderDetailDAO
}
//Main产品
type RDBMainDAO struct{}
//SaveOrderMain ...
func (*RDBMainDAO) SaveOrderMain() {
fmt.Print("rdb main save\n")
}
//Detail产品
type RDBDetailDAO struct{}
// SaveOrderDetail ...
func (*RDBDetailDAO) SaveOrderDetail() {
fmt.Print("rdb detail save\n")
}
//RDBDAOFactory 是RDB 抽象工厂实现
type RDBDAOFactory struct{}
func (*RDBDAOFactory) CreateOrderMainDAO() OrderMainDAO {
return &RDBMainDAO{}
}
func (*RDBDAOFactory) CreateOrderDetailDAO() OrderDetailDAO {
return &RDBDetailDAO{}
}
建造者模式
一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。建造者模式属于对象创建型模式。根据中文翻译的不同,建造者模式又可以称为生成器模式。
建造者模式包含如下角色:
Builder:抽象建造者
ConcreteBuilder:具体建造者
Director:指挥者
Product:产品角色
优点
1.将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
- 用户使用不同的具体建造者即可得到不同的产品对象
3.可以更加精细地控制产品的创建过程
缺点
1.如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大
2.建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制
package builder
//Builder 是生成器接口
type Builder interface {
Part1()
Part2()
Part3()
}
//指挥者接口
type Director struct {
builder Builder
}
// NewDirector ...
func NewDirector(builder Builder) *Director {
return &Director{
builder: builder,
}
}
//Construct Product
func (d *Director) Construct() {
d.builder.Part1()
d.builder.Part2()
d.builder.Part3()
}
type Builder1 struct {
result string
}
func (b *Builder1) Part1() {
b.result += "1"
}
func (b *Builder1) Part2() {
b.result += "2"
}
func (b *Builder1) Part3() {
b.result += "3"
}
func (b *Builder1) GetResult() string {
return b.result
}
单例模式
单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。
package singleton
import "sync"
//Singleton 是单例模式类
type Singleton struct{}
var singleton *Singleton
var once sync.Once
//GetInstance 用于获取单例模式对象
func GetInstance() *Singleton {
once.Do(func() {
singleton = &Singleton{}
})
return singleton
}