• 详解设计模式:工厂方法模式


    工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过工厂父类定义负责创建产品的公共接口,子类负责生产具体对象。可以理解为简单工程模式的升级,解决简单工厂模式的弊端。

    本篇内容包括:关于 工厂方法模式、工厂方法模式 Demo。



    一、关于 工厂方法模式

    1、关于 工厂方法模式

    工厂方法模式,又称工厂模式、多态工厂模式和虚拟构造器模式,通过工厂父类定义负责创建产品的公共接口,子类负责生产具体对象。

    可以理解为简单工程模式的升级,解决简单工厂模式的弊端。

    如果在简单工厂模式中,扩增具体产品信息,需要对原有工厂进行改造,当需求的产品类别增加到一定程度时,工厂较负责的产品线也相对复杂,当出现问题时,所有的产品的生产将会中断。

    工厂方法模式 解决简单工厂模式的弊端,实现父类定义公共实现接口,子类负责实现创建具体的对象,这样就可以实现增加产品类时,不需要修改工厂类,而只需要修改工厂子类。

    2、关于 工厂方法模式构成

    方法工厂的构成:

    • 抽象的产品角色(Product):它是工厂类创建的所有对象的父类,封装了各种产品对象的公有方法,它的引入提高了系统的灵活性,使得在工厂类中只需要定义一个通用的工厂方法,因为所有创建的具体产品都是其子类对象。
    • 具体的产品角色(ConcreteProduct):简单工厂的创建目标,所有被创建的对象都充当这个角色的某个具体类的实例。每一个具体产品角色都集成了抽象产品角色,需要在实现在抽象产品中声明的抽象方法。
    • 抽象工厂类(AbstractFactory):提供了创建产品的接口,调用者通过它访问具体工厂的工厂方法 newProduct() 来创建产品。
    • 具体工厂类(Factory):主要是实现抽象工厂中的抽象方法,完成具体产品的创建。
    3、关于 工厂方法模式的实现

    首先,根据具体产品进行抽象,将它们的公共的代码进行抽象和提取后,封装在一个抽象产品中;

    其次,根据抽象产品,将各种不同对象的相关代码封装到不同的类中,这些类称为具体产品类,每一个具体产品都是抽象产品的子类;

    然后,提供一个抽象工厂类用于提供创建各种产品的方法,在根据具体产品,实现相应的具体工厂类,实现创建对应产品的方法;

    最后,客户端只需要调用具体工厂类的工厂方法可得到一个相应的具体产品对象。

    4、关于 工厂方法模式的优缺点

    优点:更符合开闭原则,增加一个产品类,则只需要实现其他具体的产品类和具体的工厂类即可;符合单一职责原则,每个工厂只负责生产对应的产品

    缺点:增加一个产品,就需要实现对应的具体工厂类和具体产品类;每个产品需要有对应的具体工厂和具体产品类


    二、工厂方法模式 Demo

    1、Demo 设计

    # 角色

    DemoAbstractFactory、DemoFactoryA、DemoFactoryB、DemoAbstractProduct、DemoProductA、DemoProductB

    在这里插入图片描述

    # 实现

    DemoAbstractProduct 是作为产品角色的抽象父类,DemoProductA、DemoProductB 是作为产品角色的具体实现的子类。

    DemoFactory 作为抽象工厂角色,通过抽象方法 createProduct 返回对应的工厂。DemoFactoryA、DemoFactoryB 是具体工厂,分别负责返回 DemoProductA、DemoProductB 这些具体产品。

    2、Demo 实现

    # DemoAbstractProduct 抽象产品类

    //抽象产品类
    public abstract class DemoAbstractProduct {
        //抽象产品方法
        public abstract sayHi();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    # DemoProductA 具体产品类A

    //继承抽象类实现产品A类
    public class DemoProductA extends DemoAbstractProduct {
        
        //实现抽象产品方法
        @Overide
        public abstract sayHi(){
            System.out.println("Hi, I'm ProductA");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    # DemoProductB 具体产品类B

    //继承抽象类实现产品B类
    public class DemoProductB extends DemoAbstractProduct {
        
        //实现抽象产品方法
        @Overide
        public abstract sayHi(){
            System.out.println("Hi, I'm ProductB");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    # DemoAbstractFactory 抽象工厂类

    public class DemoAbstractFactory {
        //抽象工厂方法
        public abstract Product createProduct();
    }
    
    • 1
    • 2
    • 3
    • 4

    # DemoFactoryA

    //具体工厂类DemoFactoryA
    public class DemoFactoryA extends DemoAbstractFactory {
        
        @Overide
        public Product createProduct() {
            System.out.println("生产了一个A");
            // 生产产品A
            return new DemoProductA();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    # DemoFactoryB

    //具体工厂类DemoFactoryB
    public class DemoFactoryB extends DemoAbstractFactory {
        
        @Overide
        public Product createProduct() {
            System.out.println("生产了一个B");
            // 生产产品B
            return new DemoProductB();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    3、Demo 测试
    public class Client {
        public static void main(String[] args) {
            DemoAbstractProduct product;
    				//产品A工厂
            DemoAbstractFactory factoryA = new DemoFactoryA();
            product = factoryA.createProduct();
            product.sayHi();
            //产品B工厂
            DemoAbstractFactory factoryB = new DemoFactoryN();
            product = factoryB.createProduct();
            product.sayHi();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    政安晨:【Keras机器学习示例演绎】(十四)—— 用于弱光图像增强的零 DCE
    sqli-labs搭建
    Java面试集锦-共计2题
    Python实现Token过期自动刷新并重试原请求
    独立产品灵感周刊 DecoHack #026 - 在哪里推广你的新产品
    6. 测度论-期望及其性质
    LeetCode --- 1502. Can Make Arithmetic Progression From Sequence 解题报告
    Nginx - 本机读取服务器图像、视频
    【树莓派】起步(Snappy Ubuntu Core)
    Mac电脑配置Flutter开发环境
  • 原文地址:https://blog.csdn.net/weixin_45187434/article/details/128050174