抽象工厂模式(Abstract Factory Pattern)是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。
介绍
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
主要解决:主要解决接口选择的问题。
何时使用:系统的产品有多于一个的产品族,而系统只消费其中某一族的产品。
如何解决:在一个产品族里面,定义多个产品。
关键代码:在一个工厂里聚合多个同类产品。
应用实例:工作了,为了参加一些聚会,肯定有两套或多套衣服吧,比如说有商务装(成套,一系列具体产品)、时尚装(成套,一系列具体产品),甚至对于一个家庭来说,可能有商务女装、商务男装、时尚女装、时尚男装,这些也都是成套的,即一系列具体产品。假设一种情况(现实中是不存在的,要不然,没法进入共产主义了,但有利于说明抽象工厂模式),在您的家中,某一个衣柜(具体工厂)只能存放某一种这样的衣服(成套,一系列具体产品),每次拿这种成套的衣服时也自然要从这个衣柜中取出了。用 OOP 的思想去理解,所有的衣柜(具体工厂)都是衣柜类的(抽象工厂)某一个,而每一件成套的衣服又包括具体的上衣(某一具体产品),裤子(某一具体产品),这些具体的上衣其实也都是上衣(抽象产品),具体的裤子也都是裤子(另一个抽象产品)。
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。
go实现抽象工厂模式
/// abstract_factory.go
package abstract_factory
import "fmt"
/*
1.为【形状】创建接口
*/
type IShape interface {
Draw()
}
/*
2.创建实现【形状】接口的实体类
*/
// Square类
type Square struct {
}
func (s *Square) Draw() {
fmt.Println("Draw a [Square].")
}
// Circle类
type Circle struct {
}
func (c *Circle) Draw() {
fmt.Println("Draw a [Circle].")
}
// Rectangle类
type Rectangle struct {
}
func (r *Rectangle) Draw() {
fmt.Println("Draw a [Rectangle].")
}
/*
3.为【颜色】创建接口
*/
type IColor interface {
Fill()
}
/*
4.创建实现【颜色】接口的实体类
*/
// Red类
type Red struct {
}
func (r *Red) Fill() {
fmt.Println("Fill in [Red].")
}
// Green类
type Green struct {
}
func (g *Green) Fill() {
fmt.Println("Fill in [Green].")
}
// Blue类
type Blue struct {
}
func (g *Blue) Fill() {
fmt.Println("Fill in [Blue].")
}
/*
5.抽象工厂接口,各种类型的工厂共享(这里指ShapeFactory和ColorFactory)
*/
type IAbstractFactory interface {
getShape(int) IShape
getColor(int) IColor
}
/*
6.创建Shape工厂和Color工厂的实体类
*/
const (
SHAPE_FACTORY = iota
SQUARE
CIRCLE
RECTANGLE
COLOR_FACTORY
RED
GREEN
BLUE
)
/// ShapeFactory类
type ShapeFactory struct {
}
func (sf *ShapeFactory) getShape(shapeType int) IShape {
switch shapeType {
case SQUARE:
return &Square{}
case CIRCLE:
return &Circle{}
case RECTANGLE:
return &Rectangle{}
}
return nil
}
// 无实义,仅用来保证ShapeFactory实现了IAbstractFactory接口
func (sf *ShapeFactory) getColor(shapeType int) IColor {
return nil
}
/// ColorFactory类
type ColorFactory struct {
}
func (cf *ColorFactory) getColor(colorType int) IColor {
switch colorType {
case RED:
return &Red{}
case GREEN:
return &Green{}
case BLUE:
return &Blue{}
}
return nil
}
// 无实义,仅用来保证ColorFactory实现了IAbstractFactory接口
func (cf *ColorFactory) getShape(colorType int) IShape {
return nil
}
/*
7.建立超级工厂类,用于获取工厂实例
*/
type FactoryProducer struct {
}
func (af *FactoryProducer) getFactory(factoryType int) IAbstractFactory {
switch factoryType {
case SHAPE_FACTORY:
defer fmt.Println("[ShapeFactory] has been built...")
return &ShapeFactory{}
case COLOR_FACTORY:
defer fmt.Println("[ColorFactory] has been built...")
return &ColorFactory{}
}
return nil
}
test文件如下:
/// abstract_factory_test.go
package abstract_factory
import "testing"
func TestMain(t *testing.T) {
var factory_producer = new(FactoryProducer)
shape_factory := factory_producer.getFactory(SHAPE_FACTORY)
shape_factory.getShape(RECTANGLE).Draw()
shape_factory.getShape(CIRCLE).Draw()
shape_factory.getShape(SQUARE).Draw()
color_factory := factory_producer.getFactory(COLOR_FACTORY)
color_factory.getColor(BLUE).Fill()
color_factory.getColor(RED).Fill()
color_factory.getColor(GREEN).Fill()
}
运行结果:
[ShapeFactory] has been built...
Draw a [Rectangle].
Draw a [Circle].
Draw a [Square].
[ColorFactory] has been built...
Fill in [Blue].
Fill in [Red].
Fill in [Green].
PASS
ok Design_Patterns/2.Abstract_Factory_Pattern/go 2.295s
结果与我们预期一致。
rust实现抽象工厂模式
/*
1.为【形状】创建trait
*/
pub trait IShape {
fn draw(&self);
}
/*
2.创建实现【形状】trait的实体类
*/
/// Square类
struct Square {}
impl IShape for Square {
fn draw(&self) {
println!("Draw a [Square].");
}
}
/// Circle类
struct Circle {}
impl IShape for Circle {
fn draw(&self) {
println!("Draw a [Circle].")
}
}
/// Rectangle类
struct Rectangle {}
impl IShape for Rectangle {
fn draw(&self) {
println!("Draw a [Rectangle].")
}
}
/*
3.为【颜色】创建接口
*/
pub trait IColor {
fn fill(&self);
}
/*
4.创建实现【颜色】接口的实体类
*/
/// Red类
struct Red {}
impl IColor for Red {
fn fill(&self) {
println!("Fill in [Red].");
}
}
/// Green类
struct Green {}
impl IColor for Green {
fn fill(&self) {
println!("Fill in [Green].");
}
}
/// Blue类
struct Blue {}
impl IColor for Blue {
fn fill(&self) {
println!("Fill in [Blue].")
}
}
/*
5.抽象工厂trait,各种类型的工厂共享(这里指ShapeFactory和ColorFactory)
*/
/// 工厂类型枚举
enum FactoryType {
ShapeFactory,
ColorFactory
}
/// Shape类型枚举
pub enum ShapeType {
Square,
Circle,
Rectangle
}
/// Color类型枚举
pub enum ColorType {
Red,
Green,
Blue
}
pub trait IAbstractFactory {
fn get_shape(&self, shape_type: &ShapeType) -> Option<Box<dyn IShape>>;
fn get_color(&self, color_type: &ColorType) -> Option<Box<dyn IColor>>;
}
/*
6.创建Shape工厂和Color工厂的实体类
*/
struct ShapeFactory {}
impl IAbstractFactory for ShapeFactory {
// fn new() -> Self {
// ShapeFactory{}
// }
fn get_shape(&self, shape_type: &ShapeType) -> Option<Box<dyn IShape>> {
match shape_type {
ShapeType::Square => Some(Box::new(Square{})),
ShapeType::Circle => Some(Box::new(Circle{})),
ShapeType::Rectangle => Some(Box::new(Rectangle{})),
}
}
// getColor
fn get_color(&self, _color_type: &ColorType) -> Option<Box<dyn IColor>> {
return None;
}
}
struct ColorFactory {}
impl IAbstractFactory for ColorFactory {
// fn new() -> Self {
// ColorFactory{}
// }
fn get_color(&self, color_type: &ColorType) -> Option<Box<dyn IColor>> {
match color_type {
ColorType::Red => Some(Box::new(Red{})),
ColorType::Green => Some(Box::new(Green{})),
ColorType::Blue => Some(Box::new(Blue{})),
}
}
// getShape
fn get_shape(&self, _shape_type: &ShapeType) -> Option<Box<dyn IShape>> {
return None;
}
}
/*
7.建立超级工厂类,用于获取工厂实例
*/
struct FactoryProducer {}
impl FactoryProducer {
fn new() -> Self {
return FactoryProducer{};
}
fn get_factory(&self, factory_type: &FactoryType) -> Box<dyn IAbstractFactory> {
match factory_type {
FactoryType::ShapeFactory => Box::new(ShapeFactory{}),
FactoryType::ColorFactory => Box::new(ColorFactory{}),
}
}
}
#[test]
fn it_works() {
let factory_producer = FactoryProducer::new();
factory_producer.get_factory(&FactoryType::ShapeFactory).get_shape(&ShapeType::Square).unwrap().draw();
factory_producer.get_factory(&FactoryType::ShapeFactory).get_shape(&ShapeType::Rectangle).unwrap().draw();
factory_producer.get_factory(&FactoryType::ShapeFactory).get_shape(&ShapeType::Circle).unwrap().draw();
factory_producer.get_factory(&FactoryType::ColorFactory).get_color(&ColorType::Red).unwrap().fill();
factory_producer.get_factory(&FactoryType::ColorFactory).get_color(&ColorType::Blue).unwrap().fill();
factory_producer.get_factory(&FactoryType::ColorFactory).get_color(&ColorType::Green).unwrap().fill();
}
输出结果如下:
running 1 test
Draw a [Square].
Draw a [Rectangle].
Draw a [Circle].
Fill in [Red].
Fill in [Blue].
Fill in [Green].
test it_works ... ok
输出结果与我们预期一致。
网友评论