工厂模式
创建型模式对实例化进行抽象,将对象的创建和使用进行分离。外界只需知道对应的公共接口,不需要知道内部的具体实现细节。符合单一职责原则。
简单工厂模式
简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。简单工厂模式包含如下角色:
- 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
- 具体产品:实际创建的目标对象;
- 工厂:负责实现创建所有实例的内部逻辑。
扩展需注意:添加新产品必须修改工厂逻辑,在产品类型较多时,有可能造成工厂逻辑过于复杂,不利于系统的扩展和维护。
C++代码示例
/**
* 抽象产品
*/
class Shape {
public:
virtual void draw() = 0;
};
/**
* 具体产品:圆形
*/
class Circle : public Shape {
public:
void draw() {
cout << "draw a circle" << endl;
}
};
/**
* 具体产品:三角形
*/
class Rectangle : public Shape {
public:
void draw() {
cout << "draw a rectangle" << endl;
}
};
/**
* 工厂:负责实现创建所有实例的内部逻辑
*/
class ShapeFactory {
public:
Shape * createShape(string name) {
switch (name) {
case "circle": return new Circle();
case "rectangle": return Rectangle();
}
return nullptr;
}
};
Go代码示例
// 抽象产品
type IShape interface {
draw()
}
// 具体产品:圆形
type Circle struct { }
func (p *Circle) draw() {
fmt.Println("draw a circle")
}
// 具体产品:三角形
type Rectangle struct { }
func (p *Rectangle) draw() {
fmt.Println("draw a rectangle")
}
// 工厂
type Factory struct { }
func (p *Factory) create(name string) (IShape, error) {
// 实例化逻辑
switch name {
case "circle":
return &Circle{}, nil
case "rectangle":
return &Rectangle{}, nil
}
return nil, errors.New("unsupported name")
}
工厂方法模式
工厂方法模式(Factory Method Pattern)也称工厂模式。工厂方法模式包含以下角色:
- 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
- 具体产品:实际创建的目标对象;
- 抽象工厂:提供统一的创建产品实例的接口,产品的创建延迟到其子类(具体工厂);
- 具体工厂:负责具体的某类实例的创建。
工厂方法模式相比于简单工厂模式,将创建实例的内部逻辑由 “工厂” 转移到 “客户端” 。
C++代码示例
/**
* 抽象产品
*/
class Shape {
virtual void draw() = 0;
};
/**
* 具体产品:圆形
*/
class Circle : public Shape {
public:
void draw() {
cout << "draw a circle" << endl;
}
};
/**
* 具体产品:三角形
*/
class Rectangle : public Shape {
public:
void draw() {
cout << "draw a rectangle" << endl;
}
};
/**
* 抽象工厂
*/
class Factory {
public:
virtual Shape * createShape() = 0;
};
/**
* 具体工厂:圆形工厂
*/
class CircleFactory : Factory {
public:
Shape * createShape() {
return new Circle();
}
};
/**
* 具体工厂:三角形工厂
*/
class RectangleFactory : Factory {
public:
Shape * createShape() {
return new Rectangle();
}
};
Go代码示例
// 抽象产品
type IShape interface {
Draw()
}
// 具体产品:圆形
type Circle struct { }
func (p *Circle) Draw() {
fmt.Println("draw a circle")
}
// 具体产品:三角形
type Rectangle struct { }
func (p *Rectangle) Draw() {
fmt.Println("draw a rectangle")
}
// 抽象工厂
type IFactory interface {
CreateShape()
}
// 具体工厂:圆形工厂
type CircleFactory struct {}
func (p *CircleFactory) CreateShape() IShape {
return &Circle{}
}
// 具体工厂:三角形工厂
type RectangleFactory struct {}
func (p *RectangleFactory) CreateShape() IShape {
return &Rectangle{}
}
抽象工厂模式
抽象工厂模式包含以下角色:
- 抽象产品:所有具体产品的父类,负责描述所有实例所共有的公共接口;
- 具体产品:实际创建的目标对象;
- 抽象工厂:提供统一的创建产品实例的接口,产品的创建延迟到其子类(具体工厂);
- 具体工厂:负责具体的某类实例的创建。
从角色来看,抽象工厂模式与工厂方法模式一致。两者的区别在于,工厂方法模式中每个具体工厂只创建一类产品对象,若一个工厂需要负责多个类型的实例创建,此时适合使用抽象工厂模式。例如,戴尔工厂负责生产戴尔鼠标、戴尔键盘,惠普工厂负责生产惠普鼠标、惠普键盘。
C++代码示例
/** 抽象产品 **/
class IMouse {
public:
virtual void use() = 0;
};
class IKeyboard {
public:
virtual void use() = 0;
};
/** 具体产品 **/
class DellMouse : public IMouse {
public:
void use() {
cout << "use Dell mouse" << endl;
}
};
class DellKeyBoard : public IKeyboard {
public:
void use() {
cout << "use Dell keyboard" << endl;
}
};
class HPMouse : public IMouse {
public:
void use() {
cout << "use HP mouse" << endl;
}
};
class HPKeyBoard : public IKeyboard {
public:
void use() {
cout << "use HP keyboard" << endl;
}
};
/** 抽象工厂 **/
class IFactory {
public:
virtual IMouse * createMouse() = 0;
virtual IKeyboard * createKeyboard() = 0;
};
/** 具体工厂 **/
// 戴尔工厂生产戴尔鼠标、戴尔键盘
class DellFactory : public IFactory {
public:
IMouse * createMouse() {
return new DellMouse()
}
IKeyboard * createKeyboard() {
return new DellKeyBoard();
}
};
// 惠普工厂生产惠普鼠标、惠普键盘
class HPFactory : public IFactory {
public:
IMouse * createMouse() {
return new HPMouse()
}
IKeyboard * createKeyboard() {
return new HPKeyBoard();
}
};
Go代码示例
// 抽象产品
type IMouse interface {
Use()
}
type IKeyboard interface {
Use()
}
// 具体产品
type DellMouse struct {}
type DellKeyboard struct {}
type HPMouse struct {}
type HPKeyboard struct {}
func (d *DellMouse) Use() {
fmt.Println("user Dell mouse")
}
func (d *DellKeyboard) Use() {
fmt.Println("use Dell keyboard")
}
func (h *HPMouse) Use() {
fmt.Println("use HP mouse")
}
func (h *HPKeyboard) Use() {
fmt.Println("use HP keyboard")
}
// 抽象工厂
type IFactory interface {
CreateMouse() IMouse
CreateKeyboard() IKeyboard
}
// 具体工厂
// 戴尔工厂生产戴尔鼠标、戴尔键盘
type DellFactory struct {}
// 惠普工厂生产惠普鼠标、惠普键盘
type HPFactory struct {}
func (d *DellFactory) CreateMouse() IMouse {
return &DellMouse{}
}
func (d *DellFactory) CreateKeyboard() IKeyboard {
return &DellKeyboard{}
}
func (h *HPFactory) CreateMouse() IMouse {
return &HPMouse{}
}
func (h *HPFactory) CreateKeyboard() IKeyboard {
return &HPKeyboard{}
}
参考:
- 《大话设计模式》 程杰
- 图说设计模式-简单工厂模式
- 图说设计模式-工厂方法模式
- 图说设计模式-抽象工厂模式
- 抽象工厂模式和工厂模式的区别?