[设计模式]两种方法实现简单工厂模式

【设计模式】简单工厂模式与工厂方法模式详细解读 1.前言     设计模式,各具特色,今天在此总结一下常见模式中 简单工厂模式与工厂方法模式的区别与联系 2.两种模式概要    1. 简单工厂模式         对于简单工厂模式的介绍,请参考我的另外一篇博客  代码无错就是优?----简单工厂模式     2. 工厂方法模式   工厂方法模式又称工厂模式,也叫虚拟构造器模式属于类的创建型模式  在工厂方法模式中,父类负 阅读详情

<!--完整代码下载链接:点击下载完整代码示例-->

1.描述

在项目开发中经常会遇到根据不同的条件创建不同的对象,然后对该对象进行操作,一般都包括许多的switch -case分支如下:
CBase* pBase(NULL);
switch (type_variable)
{
    case obj1: pBase = new CBaseDerivate1();break;
    case obj2: pBase = new CBaseDerivate2();break;

    ...

    case objN: pBase = new CBaseDerivateN();break;
}

或者形如下面的情况:
CBase* pBase(NULL);

if (!strcmp(string_for_type, "Type1")) pBase = new CBaseDerivate1();
else if (!strcmp(string_for_type, "Type2")) pBase = new CBaseDerivate2();
    ...
else if (!strcmp(string_for_type, "TypeN")) pBase = new CBaseDerivateN();
上面两中创建对象的方法使用起来很繁琐,并且当对象的数量增加时,维护起来很麻烦,下面介绍简单工厂模式来解决该问,采用两种方法实现,一种是采用注册函数指针,另外一种采用模板参数。

2.两种方法实现简单工厂模式

例子:假设有一个动物类,需要根据不同的条件创建不同的动物

 方法一:采用注册函数指针的方式

      1.定义抽象动物类
      
class IAnimal
{
public:
    virtual int GetNumberOfLegs() const = 0;
    virtual void Speak() = 0;
    virtual void Free() = 0;
}; 
2.定义具体的动物实例
// IAnimal implementations
class Cat : public IAnimal
{
public:
    int GetNumberOfLegs() const { return 4; }
    void Speak() { cout << “Meow” << endl; }
    void Free() { delete this; }

    static IAnimal * __stdcall Create() { return new Cat(); }
};

class Dog : public IAnimal
{
public:
    int GetNumberOfLegs() const { return 4; }
    void Speak() { cout << “Woof” << endl; }
    void Free() { delete this; }

    static IAnimal * __stdcall Create() { return new Dog(); }
};

class Spider : public IAnimal // Yeah it isn’t really an animal…
{
public:
    int GetNumberOfLegs() const { return 8; }
    void Speak() { cout << endl; }
    void Free() { delete this; }

    static IAnimal * __stdcall Create() { return new Spider(); }
};

class Horse : public IAnimal
{
public:
    int GetNumberOfLegs() const { return 4; }
    void Speak() { cout << “A horse is a horse, of course, of course.” << endl; }
    void Free() { delete this; }

    static IAnimal * __stdcall Create() { return new Horse(); }
};

3.定义工厂
  定义创建对象函数指针:
typedef IAnimal* (__stdcall *CreateAnimalFn)(void); 
// Factory for creating instances of IAnimal
class AnimalFactory
{
private:
    AnimalFactory();
    AnimalFactory(const AnimalFactory &) { }
    AnimalFactory &operator=(const AnimalFactory &) { return *this; }

    typedef map FactoryMap;
    FactoryMap m_FactoryMap;
public:
    ~AnimalFactory() { m_FactoryMap.clear(); }

    static AnimalFactory *Get()
    {
        static AnimalFactory instance;
        return &instance;
    }

    void Register(const string &animalName, CreateAnimalFn pfnCreate);
    IAnimal *CreateAnimal(const string &animalName);
};
构造函数进行具体创建函数的注册
/* Animal factory constructor.
Register the types of animals here.
*/
AnimalFactory::AnimalFactory()
{
    Register(“Horse”, &Horse::Create);
    Register(“Cat”, &Cat::Create);
    Register(“Dog”, &Dog::Create);
    Register(“Spider”, &Spider::Create);
}

注册函数:
void AnimalFactory::Register(const string &animalName, CreateAnimalFn pfnCreate)
{
    m_FactoryMap[animalName] = pfnCreate;
}

创建实例接口:
IAnimal *AnimalFactory::CreateAnimal(const string &animalName)
{
    FactoryMap::iterator it = m_FactoryMap.find(animalName);
    if( it != m_FactoryMap.end() )
    return it->second();
    return NULL;
}

客户端使用方法:
int main( int argc, char **argv )
{
    IAnimal *pAnimal = NULL;
    string animalName;

    while( pAnimal == NULL )
    {
        cout << “Type the name of an animal or ‘q’ to quit: “;
        cin >> animalName;

        if( animalName == “q” )
        break;

        IAnimal *pAnimal = AnimalFactory::Get()->CreateAnimal(animalName);
        if( pAnimal )
        {
            cout << “Your animal has ” << pAnimal->GetNumberOfLegs() << ” legs.” << endl;
            cout << “Your animal says: “;
            pAnimal->Speak();
        }
        else
        {
            cout << “That animal doesn’t exist in the farm! Choose another!” << endl;
        }
        if( pAnimal )
            pAnimal->Free();
        pAnimal = NULL;
        animalName.clear();
    }
    return 0;
}

 方法二:采用模板参数的方式

   方法一需要每个子类都写一个创建实例的函数create,存在大量重复,同时,各个实例需要继承同一个父类,同时该方法比较容易理解。
  下面采用模板参数的方法。

   1.首先定义如下两个模板类

template <class BT>
class FactoryPlant
   {
   public:
      FactoryPlant() {}
      virtual ~FactoryPlant() {}
      virtual BT *createInstance() = 0;
   };

template <class BT,class ST>
class Factory : public FactoryPlant<BT>
   {
   public:
      Factory() {}
      virtual ~Factory() {}
      virtual BT *createInstance() {return new ST;}
   };

FactoryPlant为实际工厂类,Factory类有两个参数,一个是抽象基类BT,另一个是待实例化的类ST。 FactoryPlant 包含创建实例的纯虚函数createInstance,子类Factory实现该方法。

2.创建具体子类
 //抽象动物接口
class IAnimal
{
public:
	virtual int GetNumberOfLegs() const = 0;
	virtual void Speak() = 0;
	virtual void Free() = 0;
	typedef FactoryPlant<IAnimal> SimpleBaseClassFactory;
};

class Cat : public IAnimal
{
public:
	int GetNumberOfLegs() const { return 4; }
	void Speak() { cout << "Meow" << endl; }
	void Free() { delete this; }
    static Factory<IAnimal,Cat> myFactory;
};
Factory<IAnimal,Cat> Cat::myFactory;

class Dog : public IAnimal
{
public:
	int GetNumberOfLegs() const { return 4; }
	void Speak() { cout << "Woof" << endl; }
	void Free() { delete this; }
	static Factory<IAnimal,Dog> myFactory;
};
Factory<IAnimal,Dog> Dog::myFactory;

class Spider : public IAnimal // 
{
public:
	int GetNumberOfLegs() const { return 8; }
	void Speak() { }
	void Free() { delete this; }
	static Factory<IAnimal,Spider> myFactory;
};
Factory<IAnimal,Spider> Spider::myFactory;

class Horse : public  IAnimal
{
public:
	int GetNumberOfLegs() const { return 4; }
	void Speak() { cout << "A horse is a horse, of course, of course." << endl; }
	void Free() { delete this; }

	static Factory<IAnimal,Horse> myFactory;
};
Factory<IAnimal,Horse> Horse::myFactory;
 上面不是采用函数指针,而是每个子类采用一个静态的factory实例,由于是静态的成员,需要在类外面进行定义,否则编译将会出现 unresolved externals的错误。

3.创建函数
IAnimal *CreateAnimal(std::map<string,IAnimal::SimpleBaseClassFactory *> &factories,const string &animalName)
{
	return  factories[animalName]->createInstance();
}
4.客户端使用
void main()
{

	IAnimal  *pAnimal    = NULL;
	//Register 
	std::map<string,IAnimal::SimpleBaseClassFactory *>  factories;
	factories["Cat"] = &Cat::myFactory;
	factories["Dog"] = &Dog::myFactory;
	factories["Spider"] = &Spider::myFactory;
	factories["Horse"] = &Horse::myFactory;

	string animalName;
	while( pAnimal == NULL )
	{
		cout << "Type the name of an animal or 'q' to quit: ";
		cin >> animalName;

		if( animalName == "q" )
			break;

		IAnimal *pAnimal = CreateAnimal(factories,animalName);
		if( pAnimal )
		{
			cout << "Your animal has " << pAnimal->GetNumberOfLegs() << " legs." << endl;
			cout << "Your animal says: ";
			pAnimal->Speak();
		}
		else
		{
			cout << "That animal doesn't exist in the farm! Choose another!" << endl;
		}
		if( pAnimal )
			pAnimal->Free();
		pAnimal = NULL;
		animalName.clear();
	}

上面的map的创建是在主函数中,在比较复杂的场景中,可以在一个单例中创建该map,如果需要添加实例化其他的类,只需要将该类的factory添加到map中即可。








简单工厂模式(Java、Python)、工厂方法模式(Java、Python) 一、试画出简单工厂模式的模式结构图,并对模式进行分析 1.1 简单工厂模式结构图: 图1 简单工厂模式的模式结构图 由图1可知,简单工厂模式包含以下3个角色: Factory(工厂角色):工厂角色即工厂类,它是简单工厂模式的核心,负责实现创建所有产品实例的内部逻辑;工厂类可以被外界直接调用,创建所需的产品对象;在工厂类中提供了静态的工厂方法factoryMethod(),它的返回类型为抽象产品类型Product; Product(抽象产品角色):它是工厂类创建的所有对象的父类,封装... 阅读详情

相关推荐

离线AI实战指南:本地部署大模型处理PDF/Word/Excel

离线AI是指在无网络、不上传数据前提下,于个人设备运行大语言模型并完成文档理解、多轮对话与代码辅助等任务的技术方案。其核心依赖本地模型推理、文档解析向量化和轻量级对话调度三大能力。随着Phi-3、Qwen2、Llama3等轻量化开源模型普及,以及Ollama、LM Studio等易用工具成熟,普通用户已可在主流笔记本上实现PDF摘要、合同比对、代码注释等真实办公场景。本文聚焦离线AI的硬件适配、模型选型、文件处理链路与知识库构建,尤其强调中文OCR支持、结构化文档提取与CPU/GPU混合推理优化,助力非开发

weixin_31968639的博客 490

1024

节日快乐

hc1428090104的博客 8万+

更多 LSTM 变种——应用于 CMAPSS 数据集

本文并模型介绍,只是把一些比较火的技术,像双向注意力机制,自注意力机制这样的比较火的内容,简单的和LSTM堆叠,结果发现效果都不如最基础的,这里作者将本人代码及实现结果,进行展示,给各位想更改LSTM的朋友一些。

2301_77491330的博客 1765

小熊工厂 bt

Welcome to my blog!小熊工厂 软件大小:20986 KB软件语言:简体中文软件类别:国产软件 / 共享版 / 趣味软件应用平台:Win9x/NT/2000/XP/2003界面预览:无插件情况: 投诉更新时间:2006-09-22 14:55:33下载次数:4426推荐等级:联 系 人:ricky408163.com开 发 商:小熊工厂

xiaome4242的专栏 2万+

【全开源】废品回收垃圾回收小程序APP公众号源码PHP版本

废品回收小程序是一款基于移动端的应用程序,它提供了废品分类、预约回收、积分兑换等多种功能,帮助用户更方便地进行废品回收,同时还能兑换到一些小礼品或优惠券,让回收变得更加有趣和有价值。随着环保意识的逐渐提高,废品回收成为了我们日常生活中的重要一环。但是,如何更方便、高效地进行废品回收呢?今天,我要向大家推荐一款超级实用的工具——废品回收小程序!废品回收小程序不仅让我们的生活更加便捷,还让我们为环保事业贡献了一份力量。让我们一起行动起来,用废品回收小程序为我们的家园添一抹绿色吧!

2401_84593614的博客 1359

[网络安全自学篇] 二.Chrome浏览器保留密码功能渗透解析及登录加密入门笔记

最近开始学习网络安全相关知识,接触了好多新术语,感觉自己要学习的东西太多,真是学无止境,也发现了好几个默默无闻写着博客、做着开源的大神。接下来系统分享一些网络安全的自学笔记,希望读者们喜欢。 上一篇文章分享了看雪Web安全总结知识和一个异或解密的示例,本篇文章着重讲解Chrome浏览器保留密码功能渗透解析及登录加密入门笔记,结合实际例子一步步实现浏览器漏洞的挖掘。非常基础的文章,希望对入门的博友们有帮助,大神请飘过,谢谢各位看官!

杨秀璋的专栏 2万+

2019-10-24

今天快乐,不知不觉两年多了

Json的知识梦工厂 7073

Go游戏服务器开发的一些思考(一):语言层面

Go是比C++更好用的高级语言使用Go作为服务器开发的主语言前,首先需要对Go语言做下定性。在接触Go前,可能给人的印象(至少是我),Go是一门脚本语言。看了 官方文档 ,才知道Go是一门高级语言。与C++相比,它有以下优势: 面向接口的编程没有C++复杂的面向对象语法,如类、继承、多态、虚函数等等。Go中只有结构与接口,从语言层面上,直接指导功能与功能间的解耦。直接且语法简单 提供语言反射机制提供

范安崇的博客 9559

简单工厂、工厂方法和抽象工厂的区别

现在有2种产品需要生产,各个工厂模式的方式简单工厂:    产品类和工厂类耦合在一起。          有一个工厂,里面有二条流水线,只能生产A、B,如果工厂要增加新产品,需要对工厂进行翻修,要有第三条流水线。  工厂方法:    产品类未抽象,工厂抽象出来了。   A工厂里一条流水线生产A,B工厂一条流水线生产B,如果此时要有第三种产品,则有C工厂去生产C。   父工厂通过统一的装修模式,来声...

木子固的专栏 9075

基于ESP32和OV5640的目标检测系统

本文详细介绍了基于ESP32-S3和OV5640摄像头构建目标检测系统的完整方案。系统采用YOLOv8-Nano轻量级模型,通过INT8量化实现边缘部署,在UXGA分辨率下达到25fps帧率。文章从硬件选型、图像采集优化、模型量化部署、实时推理流水线构建等维度展开,重点解决了内存管理、电源稳定性和异常处理等嵌入式系统关键问题。该方案在资源受限条件下实现了150ms以内的端到端延迟,为物联网视觉应用提供了低成本、低功耗的解决方案,适用于智能家居、工业检测等多个场景。

reset2021的博客 329

【Java开发者必看】LangChain4j实战指南:使用AIService轻松集成聊天记忆Chat Memory到SpringBoot应用,通过封装多轮复杂对话,使聊天记忆的实现变得简单

聊天记忆是指在与用户的多轮对话过程中,能够记住之前的交互内容,从而提供更加连贯和个性化的回复。LangChain4j支持通过ChatMemoryProvider接口实现聊天记忆功能。

Spring Boot-Common On With You 448

Java设计模式--简单工厂模式

Java设计模式–简单工厂模式 文章目录Java设计模式--简单工厂模式前言一、工厂模式是什么?定义二、工厂模式的优缺点优点:缺点:三、模式的结构与实现四、应用场景 前言 现实生活中,原始社会自给自足(没有工厂),农耕社会小作坊(简单工厂,民间酒坊),工业革命流水线(工厂方法,自产自销),现代产业链代工厂(抽象工厂,富士康)。我们的项目代码同样是由简到繁一步一步迭代而来的,但对于调用者来说,却越来越简单 一、工厂模式是什么? 定义 工厂模式的定义:定义一个创建产品对象的工厂接口,将产品对象的实际创建工

weixin_43127250的博客 127

上位机 寻边器 通讯实战

寻边器通讯接口实现 本文介绍了上位机与盖泽(Gazer)和JEL品牌寻边器的通讯接口实现方案。主要内容包括: 接口定义:创建了IAlignerOperation接口,定义了获取状态、控制运动、真空吸附等核心功能。 具体实现: 盖泽寻边器(GazerAlignerCjh):通过串口通讯,实现了回零、校准、移动位置等操作 JEL寻边器(JelAligner):同样基于串口通讯,包含错误处理、状态查询等功能 工厂模式:通过AlignerFactory工厂类根据设备品牌创建对应的实现对象。 设备加载:展示了如何在系

StevenChen的博客 375

设计模式(19):创建型-简单工厂模式(Simple Factory)及工厂方法模式(Factory Method)

设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。 设计模式分为三种类型,共23种。 创建型模式(5):单例模式、抽象工厂模式、建造者模式...

後雪寒的专栏 632

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

工厂方法模式_工厂方法模式浅析

在平时的应用开发中,工厂模式是比较常用的一个设计模式,基本上在很多的开源jar中可以看到工厂设计模式的影子。工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定哪一个类实例化,不必事先知道每次要实例化哪一个类。工厂模式有以下几种形态:简单工厂(Simple Factory)模式:又称静态工厂方法模式。工厂方法(Factory Method)模式:又称多态性工厂(Polymor...

weixin_39701768的博客 277

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

学习记录-----GOF的23种设计模式__工厂方法模式

工厂模式的定义:定义一个用于创建产品对象的工厂,将对象的实际创建工作交给工厂来进行创建,满足创建型模式的“创建与使用相分离的特点”。 简单工厂模式不在23种设计模式之列,是一种简化的工厂方法模式。 工厂方法模式和抽象工厂模式属于五种创建型模式的两种(创建型模式有:单例模式、原型模式、工厂方法模式、抽象工厂模式、建造者模式)。简单工厂模式不在23种设计模式之列。 简单工厂在创建实例时通常是静态方法创建,可以生产多种产品。 简单工厂在创建实例时没新增一种产品则需要新增一个工厂类和一个具体产品类,违背了“开闭原则

dzd9527的博客 288

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

使用静态工厂方法的好处和坏处

前言: 清晰性和简介性是最为重要的 一个模块的使用者永远也不应该被模块的行为所迷惑(那样就不清晰了),模块要尽可能的小,但又不能太小【术语模块(module):是指任何可重用的软件组件,从单个方法到包含多个包的复杂系统都可以是一个模块】。代码应该被重用,而不是拷贝,模块之间的相依性应该尽可能降低到最小,错误应该尽早被检测出来,理想的情况下是在编译的时刻。 NO.1 考虑用静态...

djh10000的博客 222

java web简单工厂模式_JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下, new操作符直接生成对象会带来一些问题。举例来说, 许多类型对象的创造需要一系列的步骤: 你可能需要计算或取得对象的初始设置; 选择生成哪个子对象实例; 或在生成你需要的对象之前必须先生成一些辅助功能的对象。 在这些情况,新对象的建立就是一个 “过程”,不仅是一个操作,像一部...

weixin_35554771的博客 153

“简单工厂模式”和“工厂方法模式”学习,并找出“简单工厂模式”和“工厂方法模式”区别

从不同角度对比分析“简单工厂模式”和“工厂方法模式”简单工厂模式简单工厂模式概念简单工厂模式结构与实现工厂方法模式对比分析“简单工厂模式”和“工厂方法模式” 简单工厂模式 简单工厂模式概念     简单工厂模式并不属于GoF的23种经典设计模式,但通常将它作为学习其他工厂模式的基础。     简单工厂模式(Simple Factory Pattern): 定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具

贰十二的博客 225

设计模式 工厂方法

目录 1.工厂方法 2.静态工厂方法 1.工厂方法 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。 工厂方法即Factory Method,是一种对象创建型模式。 工厂方法的目的是使得创建对象和使用对象是分离的,并且客户端总是引用抽象工厂和抽象产品 package com.learn.factorymethod; public interface Factory { Number parse(String s).

sinat_31089473的博客 307

设计模式——简单工厂模式

工厂具有不同职能部门,工厂具有逻辑判断功能,一个工厂实现不同类的创建。 一、简单工厂模式 实现代码: class operationfactory { public static operation creationoperation(String operation) { operation oper=null; switch(operation) { case "+":oper=new add1();break; case "-":oper=new subtract();

weixin_45294429的博客 167

几个问题(八)-------使用静态工厂方法的好处和坏处

beidou321的专栏 4512

简单工厂模式和工厂方法模式

简单工厂模式是指专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 从图中我们可以清楚的看到,该模式中主要包含下面3种角色: 工厂(Creator)角色 它是工厂模式的核心,负责实现创建所有势力的内部逻辑。工厂类可以被外界直接调用,创建所需的产品的对象。 抽象(Product)角色 简单工厂模式所创建的所有对象的父类,负责描述所有实例所共

lzy20ls的博客 6504

了解一下简单工厂模式概述和使用

设计模式(简单工厂模式概述和使用)(了解) A:简单工厂模式概述: 又叫静态工厂方法模式,它定义一个具体的工厂类负责创建一些类的实例。 B:优点 客户端不需要在负责对象的创建,从而明确了各个类的职责。 C:缺点 这个静态工厂类负责所有对象的创建,如果有新的对象增加,或者某些对象的创建方式不同,就需要不断的修改工厂类,不利于后期的维护。 D:案例演示 动物抽象类:public abstract Animal { public abstract void eat(); } 具体狗类:public class

pipizhen_的博客 517
上一篇: 流、管道和重定向
下一篇: 基于Table方法降低代码圈复杂度
xiaoding133
博客等级 码龄19年 415粉丝 159原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值