美文网首页
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