前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >大牧絮叨设计模式:工厂方法模式

大牧絮叨设计模式:工厂方法模式

作者头像
大牧莫邪
发布于 2019-07-16 07:28:20
发布于 2019-07-16 07:28:20
41000
代码可运行
举报
运行总次数:0
代码可运行

1、 工厂方法模式概述

工厂方法模式是一种创建模式,又被称为虚拟构造子模式(Virtual Constructor)或者多态性工厂模式(Polymoriphoic Factory)。工厂方法模式是目标是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中。

1.1、 工厂方法模式核心组件

工厂方法模式是在简单工厂模式上的改进,主要包含如下几个角色及组件

  • 抽象工厂(Creator):整个工厂模式的核心角色,它与应用无关,主要在创建模式中规范和产品对应的工厂对象的标准化定义。
  • 具体工厂(Concrete Creator):实现了抽象工厂的具体工厂类,该类型是和应用直接交互的具体实现类,在应用程序中调用,用于创建产品对象。
  • 抽象产品(Product):工厂方法模式创建的所有类型的超级父类,该类型和具体业务有关,用于规范工厂方法模式中创建的方法对象具备的公共特征行为。
  • 具体产品(Concrete Product):该类型实现了抽象产品 父类,是工厂方法模式中具体创建的实例对象。

image.png

1.2、 工厂方法模式优缺点

优点:

在简单工厂模式上的改进,核心工厂类不再负责所有产品的构建,而是将具体的工作交给子类进行实现,不再接触和业务相关的具体细节,如此进一步抽象的结果,最直接的作用就是在满足OCP原则的基础上实现了功能的扩展。

缺点:

软件的水平功能扩展已经非常可观,但是对于新功能扩展,灵活性上稍有欠缺,在横向扩展时如果出现新的业务逻辑就需要更改原有的工厂类型代码予以满足了。

在本章节的代码演示中,为了能用最简洁的逻辑结构说明工厂方法模式,不进行多层构建,大家看代码的时候可以自行拓展。

2、 Java实现

(1) 核心工厂声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter;

/**
 * <p>项目文档: 工厂接口</p>
 * @author 大牧
 * @version V1.0
 */
public interface IFactory<T> {
    /**
     * 获取具体产品实例的方法
     * @return 返回创建的实例对象
     */
    T product();
}

(2) 核心产品声明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter;

/**
 * <p>项目文档: 产品接口</p>
 *
 * @author 大牧
 * @version V1.0
 */
public interface IProduct {

    /**
     * 产品类型的公共方法
     * @return 返回产品信息
     */
    String getInformation();
}

(3) 产品具体实现

为了简洁起见,我们直接实现IProduct接口完成具体产品类的定义,不再进行多层声明。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter.product.impl;

import com.damu.inter.IProduct;

/**
 * <p>项目文档: 产品具体实现</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class PhoneProduct implements IProduct {
    @Override
    public String getInformation() {
        return "电视很NB,报纸很NB,杂志很NB,游戏机很NB,小说很NB,最终都被手机干掉了";
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter.product.impl;

import com.damu.inter.IProduct;

/**
 * <p>项目文档: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class ComputerProduct implements IProduct {
    @Override
    public String getInformation() {
        return "电脑,官方称呼计算机,主要用于进行数据运算的一台机器。";
    }
}

(4) 工厂具体实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter.factory.impl;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.inter.product.impl.PhoneProduct;

/**
 * <p>项目文档: 具体工厂</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class PhoneFactory implements IFactory<IProduct> {
    @Override
    public PhoneProduct product() {
        // 工厂标准方法中,完成指定产品对象的构建
        return new PhoneProduct();
    }
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu.inter.factory.impl;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.inter.product.impl.ComputerProduct;

/**
 * <p>项目文档: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class ComputerFactory implements IFactory<IProduct> {
    @Override
    public ComputerProduct product() {
        // 工厂方法标注方法:完成对象的创建并返回
        return new ComputerProduct();
    }
}

(5) 代码测试

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.damu;

import com.damu.inter.IFactory;
import com.damu.inter.IProduct;
import com.damu.inter.factory.impl.ComputerFactory;
import com.damu.inter.factory.impl.PhoneFactory;
import com.damu.inter.product.impl.ComputerProduct;
import com.damu.inter.product.impl.PhoneProduct;

/**
 * <p>项目文档: TODO</p>
 *
 * @author 大牧
 * @version V1.0
 */
public class Main {

    public static void main(String[] args) {
        // 创建工厂对象
        IFactory<IProduct> phoneFactory = new PhoneFactory();
        // 通过工厂穿件具体对象
        IProduct phoneProduct = phoneFactory.product();
        System.out.println(phoneProduct.getInformation());

        // 创建工厂对象
        IFactory<IProduct> computerFactory = new ComputerFactory();
        // 通过工厂创建具体对象
        IProduct computerProduct = computerFactory.product();
        System.out.println(computerProduct.getInformation());

    }
}

在测试代码中,我们可以观察到在获取到统一的工厂实例对象后,通过工厂实例创建的具体产品对象,是根据在构建的时候的具体工厂决定的,也就是具体工厂和具体产品之间的业务关系是比较紧密的,运行结果如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/Library/../classes com.damu.Main
电视很NB,报纸很NB,杂志很NB,游戏机很NB,小说很NB,最终都被手机干掉了
电脑,官方称呼计算机,主要用于进行数据运算的一台机器。

3、 Python实现

还原Java工厂方法模式的实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
"""
工厂方法模式
"""
import abc


class IFactory(metaclass=abc.ABCMeta):
    """工厂接口"""

    @abc.abstractmethod
    def product(self):
        raise NotImplementedError("该方法必须在工厂子类中实现")


class IProduct(metaclass=abc.ABCMeta):
    """产品接口"""

    @abc.abstractmethod
    def get_information(self):
        raise NotImplementedError("该方法必须在产品子类中实现")


class PhoneProduct(IProduct):
    """手机产品"""

    def get_information(self):
        return "电视很NB,报纸很NB,杂志很NB,游戏机很NB,小说很NB,最终都被手机干掉了"


class ComputerProduct(IProduct):
    """电脑产品"""

    def get_information(self):
        return "电脑,官方称呼计算机,主要用于进行数据运算的一台机器"


class PhoneFactory(IFactory):
    """手机工厂"""

    def product(self):
        """生产手机对象的工厂方法"""
        return PhoneProduct()


class ComputerFactory(IFactory):
    """电脑工厂"""

    def product(self):
        """生产电脑对象的工厂方法"""
        return ComputerProduct()


if __name__ == "__main__":
    """测试代码"""
    # 创建工厂实例
    phoneFactory = PhoneFactory()
    # 创建产品
    phone = phoneFactory.product()
    print(phone.get_information())

    # 创建电脑工厂
    computerFactory = ComputerFactory()
    # 创建产品
    computer = computerFactory.product()
    print(computer.get_information())

4、 Go实现

4.1、 定义工厂及产品接口

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import "fmt"

/*
定义产品接口
*/
type IProduct interface {
    // 获取产品信息的方法
    GetInformation() string
}

/*
定义工厂接口
 */
type IFactory interface {
    // 生产产品的方法
    product() IProduct
}

4.2、 构建具体产品类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
定义具体产品:手机、电脑
 */
type PhoneProduct struct {}
// 实现工厂方法
func (phone PhoneProduct) GetInformation() string {
    return "电视很NB,报纸很NB,杂志很NB,游戏机很NB,小说很NB,最终都被手机干掉了"
}

/*
产品:电脑
 */
type ComputerProduct struct{}
// 实现工厂方法
func (computer ComputerProduct) GetInformation() string {
    return "电脑,官方称呼计算机,主要用于进行数据运算的一台机器。"
}

4.3、 构建具体工厂类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/*
具体工厂:手机工厂
 */
type PhoneFactory struct{}
// 实现接口方法
func (phoneFactory PhoneFactory) product() IProduct  {
    return new(PhoneProduct)
}

/*
具体工厂:电脑工厂
 */
type ComputerFactory struct{}
// 实现接口方法
func (computerFactory ComputerFactory) product() IProduct  {
    return new(ComputerProduct)
}

4.4、测试代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main()  {
    // 创建工厂对象
    phoneFactory := new(PhoneFactory)
    // 创建具体对象
    phone := phoneFactory.product()
    fmt.Println(phone.GetInformation())

    // 创建工厂对象
    computerFactory := new(ComputerFactory)
    // 创建具体对象
    computer := computerFactory.product()
    fmt.Println(computer.GetInformation())
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.07.15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
大牧絮叨设计模式:抽象工厂模式
抽象工厂模式(Abstract Factory)[GOF95]是一种对象的创建模式,是在工厂方法模式上的又一次改进,主要应用于多等级产品结构的项目架构中,将产品对象的创建过程和产品对象的使用过程解耦合,使用抽象工厂模式的架构中业务模型从工厂对象中获取到产品对象,只需要关注产品对象的使用即可,而可能添加了较为复杂业务逻辑的创建过程封装在工厂内部,让系统中各个模块的责任更加明确。
大牧莫邪
2019/07/17
3070
大牧絮叨设计模式:简单工厂模式
简单工厂模式是一种创建模式,又称为静态工厂方法模式,但是需要注意的是它不属于GOF23种设计模式之一。
大牧莫邪
2019/07/15
4230
大牧絮叨设计模式:简单工厂模式
解决简单工厂问题:设计模式之工厂方法模式
在上一节的简单工厂模式中,我们知道简单工厂所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。
程序视点
2023/05/24
2420
解决简单工厂问题:设计模式之工厂方法模式
聊聊设计模式之工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
Bug开发工程师
2018/07/23
3620
聊聊设计模式之工厂方法模式
全面通透深入剖析工厂方法模式
(1)抽象工厂(Factory):是工厂方法模式的核心,与应用程序无关。任何在模式中创建的对象的工厂类必须实现这个接口。
Tom弹架构
2021/11/11
5200
23种设计模式(2):工厂方法模式
定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。
全栈程序员站长
2022/07/09
1930
23种设计模式(2):工厂方法模式
Java设计模式之工厂方法模式
工厂方法模式(Factory Method Pattern)是Java设计模式中的一种创建型模式,它提供了一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。这种模式属于创建型模式,它在一个超类中定义了一个创建对象的接口,但由子类决定实例化的类是哪一个。
刺槐儿
2024/01/18
2780
大牧絮叨设计模式:建造者模式
建造模式(Builder)[GOF95]是一种对象的创造模式。主要责任是在程序中创建较为复杂的对象,企业项目中在运行环境初始化时经常使用的一种创建模式。
大牧莫邪
2019/07/23
3980
一起学习设计模式--03.工厂方法模式
简单工厂模式虽然简单,但是存在一个很严重的问题:由于静态工厂方法是根据传入的参数不同来创建不同的产品的,所以当系统中需要引入新产品时,就需要修改工厂类的源代码,这将违背开闭原则。为了实现增加新产品而不修改原有代码,工厂方法模式应运而生。
独立观察员
2022/12/06
4480
一起学习设计模式--03.工厂方法模式
工厂方法模式
工厂方法模式(Factory Method)定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
卡尔曼和玻尔兹曼谁曼
2019/01/25
3620
工厂方法模式
设计模式之工厂方法模式
定义一个创建对象的接口(Abstract Factory),但由子类(Concrete Factory)决定要实例化的类是哪一个。
九转成圣
2024/04/10
810
设计模式之工厂方法模式
工厂方法模式
简单定义### 定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂方法使一个类的实例化延迟到其子类。 工厂方法(Factory Method)模式的意义### 是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。 核心精神### 是封装类中不变的部分,提取其中个性化善变的部分为独立类,通过依赖注入以达到
张俊怡
2018/04/24
5360
工厂方法模式
工厂方法模式
工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。 ——《设计模式:可复用面向对象软件的基础》
mingmingcome
2021/11/29
2330
工厂方法模式
设计模式之工厂模式系列
在开发中,工厂模式为我们提供了一种松耦合的形式,在一些需要频繁构造比较复杂的对象时,就可以使用工厂模式,通过对象工厂为我们提供实例,这样在后期维护的时候可以统一的对实例对象的过程进行管理升级。
宿春磊Charles
2022/03/29
1600
工厂方法模式(FactoryMethod)
工厂方法模式是一种创建型模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。
兜兜转转
2023/03/29
2230
工厂方法模式(FactoryMethod)
面向对象设计的设计模式(二):工厂方法模式
工厂方法模式的适用场景与简单工厂类似,都是创建数据和行为比较类似的对象。但是和简单工厂不同的是:在工厂方法模式中,因为创建对象的责任移交给了抽象工厂的子类,因此客户端需要知道其所需产品所对应的工厂子类,而不是简单工厂中的参数。
用户2932962
2019/01/09
4680
设计模式(八):工厂方法模式
定义用于创建对象的接口,让子类决定创建哪个类的实例。工厂方法允许类的实例化延迟到子类。
xujjj
2019/07/12
3940
设计模式(八):工厂方法模式
『设计模式』工厂方法模式
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
风骨散人Chiam
2020/10/28
4400
工厂方法模式
高爽
2017/12/28
5630
工厂方法模式
设计模式~工厂方法模式
之前,我们说到简单工厂模式的优点是允许客户端相对独立于产品创建的过程,并在系统引入新产品的时候无需修改客户端,也就是说,它在某种程度上支持开闭原则。
Vincent-yuan
2020/07/31
2630
设计模式~工厂方法模式
相关推荐
大牧絮叨设计模式:抽象工厂模式
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档