美文网首页
2.抽象工厂模式(Go和Rust实现)

2.抽象工厂模式(Go和Rust实现)

作者: 梁帆 | 来源:发表于2021-08-02 16:40 被阅读0次

抽象工厂模式(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

输出结果与我们预期一致。

相关文章

网友评论

      本文标题:2.抽象工厂模式(Go和Rust实现)

      本文链接:https://www.haomeiwen.com/subject/uxoqvltx.html