深入理解工厂模式:创建可复用的对象实例

这里写目录标题

  • 前言
  • 简单工厂模式
  • 工厂方法模式
  • 抽象工厂模式
  • 总结

前言

工厂模式是一种常用的设计模式,它可以帮助我们更好地组织和管理代码,将对象的创建和使用分离开来,提高代码的可维护性和扩展性。

在软件开发中,我们经常会遇到需要创建多个不同类型的对象的情况。如果每次都使用 new
关键字来实例化对象,代码会变得冗长、难以维护,并且不易于扩展。为了解决这个问题,我们可以使用工厂模式来封装对象的创建过程,使得客户端只需要关心接口而不需要关心具体的实现。
在这里插入图片描述
工厂模式包括三种变体:简单工厂模式、工厂方法模式和抽象工厂模式。

在这里插入图片描述

简单工厂模式

简单工厂模式通过一个工厂类来创建所有产品的实例。客户端只需要提供给工厂类一个参数,工厂类根据这个参数决定实例化哪个具体产品类的对象并返回给客户端。

例如,我们有一个形状接口 Shape 和三个实现类 Circle、Square 和 Rectangle。我们可以创建一个 ShapeFactory 工厂类来根据客户端传递过来的参数来实例化相应的对象。

interface Shape {
    void draw();
}
class Circle implements Shape {
    public void draw() {
        System.out.println("Inside Circle::draw() method.");
    }
}
class Square implements Shape {
    public void draw() {
        System.out.println("Inside Square::draw() method.");
    }
}
class Rectangle implements Shape {
    public void draw() {
        System.out.println("Inside Rectangle::draw() method.");
    }
}
class ShapeFactory {
    public Shape getShape(String shapeType) {
        if (shapeType == null) {
            return null;
        }
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new Circle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new Square();
        } else if (shapeType.equalsIgnoreCase("RECTANGLE")) {
            return new Rectangle();
        }
        return null;
    }
}

客户端可以通过 ShapeFactory 工厂类来获取 Shape 对象,而不需要关心具体的实现。

ShapeFactory shapeFactory = new ShapeFactory();
Shape circle = shapeFactory.getShape("CIRCLE");
circle.draw();
Shape square = shapeFactory.getShape("SQUARE");
square.draw();
Shape rectangle = shapeFactory.getShape("RECTANGLE");
rectangle.draw();

例2:


#include<iostream>
using namespace std;
class animal {
public:
	virtual void eat() = 0;
	virtual void drink() = 0;
	virtual ~animal() {}
};
class lion :public animal{
public:
	void eat() {
		cout << "lion eat meat" << endl;
	}
	void drink() {
		cout << "lion drink hongniu" << endl;
	}
	~lion() {
		cout << "animal lion delete" << endl;
	}
	
};
class panda : public animal {
public:
	void eat() {
		cout << "panda eat bamboo" << endl;
	}
	void drink() {
		cout << "panda drink water" << endl;
	}
	~panda() {
		cout << "animal panda delete" << endl;
	}
};
class factory {
public: 
	virtual animal* getanimal() = 0;
	virtual ~factory() {}
};
class lionfactory :public factory {
public:
	animal* getanimal() {
		return new lion;
	 }
	~lionfactory() {
		cout << "lion delete" << endl;
	}
};
class pandafactory : public factory {
public:
	animal* getanimal() {
		return new panda;
	}
	~pandafactory() {
		cout << "panda delete" << endl;
	}
};
int main()
{
	factory * base = new pandafactory;
	animal* test = base->getanimal();
	test->drink();
	test->eat();
	delete test;
	delete base;
	return 0;
}

在这里插入图片描述

工厂方法模式

工厂方法模式定义了一个创建对象的接口,但将具体的对象创建延迟到子类中实现。每个子类都可以通过实现工厂方法来创建属于自己的具体产品。

例如,我们有一个披萨接口 Pizza 和两个实现类 CheesePizza 和 PepperoniPizza。我们可以创建一个 PizzaStore 抽象工厂类来定义一个 createPizza 的抽象方法,而具体的实现由不同类型的 PizzaStore 子类来实现。

interface Pizza {
    void prepare();
    void bake();
    void cut();
    void box();
}
class CheesePizza implements Pizza {
    public void prepare() {
        System.out.println("Preparing Cheese Pizza");
    }
    public void bake() {
        System.out.println("Baking Cheese Pizza");
    }
    public void cut() {
        System.out.println("Cutting Cheese Pizza");
    }
    public void box() {
        System.out.println("Packing Cheese Pizza");
    }
}
class PepperoniPizza implements Pizza {
    public void prepare() {
        System.out.println("Preparing Pepperoni Pizza");
    }
    public void bake() {
        System.out.println("Baking Pepperoni Pizza");
    }
    public void cut() {
        System.out.println("Cutting Pepperoni Pizza");
    }
    public void box() {
        System.out.println("Packing Pepperoni Pizza");
    }
}
abstract class PizzaStore {
    public Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    protected abstract Pizza createPizza(String type);
}
class NYPizzaStore extends PizzaStore {
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")) {
            return new CheesePizza();
        } else if (type.equals("pepperoni")) {
            return new PepperoniPizza();
        }
        return null;
    }
}

客户端可以通过不同类型的 PizzaStore 子类来获取 Pizza 对象,而具体的实现由子类来决定。

PizzaStore nyStore = new NYPizzaStore();
Pizza cheesePizza = nyStore.orderPizza("cheese");
Pizza pepperoniPizza = nyStore.orderPizza("pepperoni");

抽象工厂模式

抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。通过使用抽象工厂,客户端可以创建多个产品家族的对象。

例如,我们有一个形状接口 Shape 和两个实现类 RedCircle 和 BlueSquare,以及一个颜色接口 Color 和两个实现类 Red 和 Blue。我们可以创建一个抽象工厂 AbstractFactory 接口来定义两个抽象方法 getShape 和 getColor,由不同类型的子类来实现。
在这里插入图片描述

interface Shape {
    void draw();
}
class RedCircle implements Shape {
    public void draw() {
        System.out.println("Inside RedCircle::draw() method.");
    }
}
class BlueSquare implements Shape {
    public void draw() {
        System.out.println("Inside BlueSquare::draw() method.");
    }
}
interface Color {
    void fill();
}
class Red implements Color {
    public void fill() {
        System.out.println("Inside Red::fill() method.");
    }
}
class Blue implements Color {
    public void fill() {
        System.out.println("Inside Blue::fill() method.");
    }
}
interface AbstractFactory {
    Shape getShape(String shapeType);
    Color getColor(String colorType);
}
class ColorFactory implements AbstractFactory {
    public Shape getShape(String shapeType) {
        return null;
    }
    public Color getColor(String colorType) {
        if (colorType.equalsIgnoreCase("RED")) {
            return new Red();
        } else if (colorType.equalsIgnoreCase("BLUE")) {
            return new Blue();
        }
        return null;
    }
}
class ShapeFactory implements AbstractFactory {
    public Shape getShape(String shapeType) {
        if (shapeType.equalsIgnoreCase("CIRCLE")) {
            return new RedCircle();
        } else if (shapeType.equalsIgnoreCase("SQUARE")) {
            return new BlueSquare();
        }
        return null;
    }
    public Color getColor(String colorType) {
        return null;
    }
}

客户端可以通过不同类型的 AbstractFactory 子类来获取 Shape 和 Color 对象。

AbstractFactory shapeFactory = new ShapeFactory();
Shape redCircle = shapeFactory.getShape("CIRCLE");
redCircle.draw();
AbstractFactory colorFactory = new ColorFactory();
Color blue = colorFactory.getColor("BLUE");
blue.fill();

例2:


#include<iostream>
#include<string>
using namespace std;
 
class shipbody {
public:
	virtual string getshipbody() = 0;
	virtual ~shipbody(){}
};
class woodbody : public shipbody{
public:
	string getshipbody() override{
		return "wood made shipbody";
	}
};
class steelbody : public shipbody {
public:
	string getshipbody()override {
		return "steel made shipbody";
	}
};

class shipmove {
public:
	virtual string getshipmove() = 0;
	virtual ~shipmove(){}
};
class humanmove :public shipmove {
public:
	string getshipmove() {
		return "human move ship";
	}
};
class fuelmove :public shipmove{
public:
	string getshipmove() {
		return "fuel move ship";
	}
};
class ship {
public:
	ship(shipbody* body,shipmove* move):m_body(body),m_move(move){}
	~ship() {
		delete m_move;
		delete m_body;
	}
	string getship() {
		string info = m_move->getshipmove() + m_body->getshipbody();
		return info;
	}
private:
	shipbody* m_body;
	shipmove* m_move;
};

class abstractfactory {
public:
	virtual ship* createship() = 0;
	virtual ~abstractfactory(){}
};
class standardfactory :public abstractfactory {
public:
	ship* createship() {
		cout << "standard finish create " << endl;
		return  new ship(new woodbody, new humanmove);
	}

};
class enhancefactory : public abstractfactory {
public:
	ship* createship() {
		cout << "enhance finish create" << endl;
		return new ship(new steelbody, new fuelmove);
	}
};
int main()
{
	abstractfactory* abs = new enhancefactory;
	ship* obj = abs->createship();
	cout<<obj->getship();
	return 0;
}

总结

总的来说,工厂模式是一种非常有用的设计模式,它可以帮助我们更好地组织和管理代码,提高代码的可维护性和扩展性。在实际开发中,我们应该根据具体的场景选择不同类型的工厂模式,以便更好地满足需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/347418.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++拷贝构造函数、赋值学习整理:

拷贝构造函数&#xff1a; 概念&#xff1a; 构造函数的第一个参数&#xff0c;是类本身的const引用&#xff08;一般情况下没有其他参数&#xff0c;少数情况&#xff1a;其他参数必须有默认值&#xff01;&#xff09;称此类构造函数为拷贝构造函数 特征&#xff1a; 1&am…

使用Animate.css动画库

1.网站&#xff1a;Animate.css | A cross-browser library of CSS animations. 样式&#xff1a;Animate.css 一款强大的预设css3动画库 (jq22.com) 一、引入 命令提示符/终端&#xff1a; npm install animate.css --save 二、 全局导入&#xff08;在main.js&#xff0…

Obsidian笔记软件结合cpolar实现安卓移动端远程本地群晖WebDAV数据同步

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

如何编写高质量测试用例?

&#x1f345; 视频学习&#xff1a;文末有免费的配套视频可观看 &#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;薪资嘎嘎涨 测试场景&#xff1a; 为登录功能设计测试用例 测试员为什么要会编测试用例 测试员的目标是…

HAL STM32+EC11编码器实现增减调节及单击、双击、长按功能

HAL STM32EC11编码器实现增减调节及单击、双击、长按功能 &#x1f4fa;实现效果演示&#xff1a; &#x1f4d8;内容提要 &#x1f4dd;本文主要实现&#xff0c;通过STM32 HAL库开发&#xff0c;实现的EC11编码器功能&#xff0c;按键结合状态机思想实现的拓展单击、双击、…

win下安装es可视化工具——elasticsearch head(win_Elasticsearch)

一、head简介 Elasticsearch Head是集群管理、数据可视化、增删改查、查询语句可视化工具。 二、node.js的安装 ElasticSearch-head 依赖于node.js 下面先安装node.js 下面是node.js下载地址http://nodejs.cn/download/&#xff1b; 下载后&#xff0c;就是一个安装包&#xf…

如何在Ubuntu安装配置SVN服务端并实现无公网ip访问内网资料库

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改au…

Java可以用于物联网的开发吗?

Java可以用于物联网的开发吗? 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「Java的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff01;&#xff01;&#xff01;J…

备忘录记事本内容转移到新手机的方法

在日常的工作和生活中&#xff0c;我习惯用备忘录来记录一切&#xff1a;工作的要点、买菜的清单、生活的琐事……这些看似微小的记录&#xff0c;却是我生活的重要组成部分。然而&#xff0c;每次换手机&#xff0c;我总是面临一个难题&#xff1a;如何将旧手机上的备忘录内容…

下沉市场哪些品牌正当红?“下沉同花顺”异军突起

文 | 螳螂观察 作者 | 易不二 2023年的消费市场&#xff0c;越来越多“农村包围城市”的下沉品牌&#xff0c;以亮眼的表现成为拉动消费复苏的主力军。 全球36000多家门店的蜜雪冰城&#xff0c;向港交所递表冲刺IPO&#xff1b;两大量贩零食巨头赵一鸣零食与零食很忙战略合…

一个响指,代码生成!华为云CodeArts Snap正式公测

月初&#xff0c;华为云CodeArts Snap正式开启公测&#xff0c;这是一款基于华为云研发大模型的智能化编程助手&#xff0c;旨在为开发者提供高效且智能的编程体验&#xff0c;提升研发人员的单兵作战能力。 如今&#xff0c;生成式AI爆发式增长&#xff0c;大模型商用节奏加快…

JVM/GC复习

JVM/GC JVM(java虚拟机)MATjstack(将正在运行的JVM的线程进行快照并且打印出来)死锁VisualVM工具(监控线程内存使用情况)JMX GC垃圾回收算法1.引用计数法2.标记清除发3.标记压缩算法4.复制算法5.分代算法 收集器1.串行垃圾收集器2.并行垃圾收集器2.CMS垃圾收集器 3.G1垃圾收集器…

威联通QNAP NAS结合cpolar内网穿透实现公网远程访问NAS中存储的文件

文章目录 推荐 前言1. 威联通安装cpolar内网穿透2. 内网穿透2.1 创建隧道2.2 测试公网远程访问 3. 配置固定二级子域名3.1 保留二级子域名3.2 配置二级子域名 4. 使用固定二级子域名远程访问 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣…

一文了解prettier

简介 eslint和prettier都是用来做代码格式化的&#xff0c;他们其中又分为npm包和vscode插件&#xff0c;顺序是&#xff1a;先有npm包再有vscode插件 eslint限制工具 作用&#xff1a; 检查代码规范变量声明是否调用是否有console.log()语句… 用法 新建index.js文件 //…

MySQL数据库的锁机制

目录 一、引言 二、锁的类型及作用 2.1 行级锁 2.2 间隙锁与临键锁 2.3 共享锁与排他锁 2.4 意向锁 2.5 表级锁 2.6 元数据锁 三、锁的管理与优化 3.1 合理设置事务隔离级别 3.2 避免长事务 3.3 索引优化 3.4 明确锁定范围 3.5 避免不必要的全表扫描 四、实战分…

JDBC数据库连接

JDBC(Java DataBase Connectivity)就是用Java语言操作关系型数据库的一套API JDBC的步骤固定&#xff0c;大体分为8个步骤&#xff0c;以MySQL数据库为例 1.创建工程并导入驱动jar包 2.注册驱动 注册驱动的目的是告诉代码要执行哪一个jar包 Class.forName(com.mysql.jdbc.D…

多尺度特征融合13种创新方案全面汇总,含2024年最新

前段时间和大佬朋友交流学术的时候&#xff0c;发现目前发论文最好用的2大创新方式一是加注意力机制&#xff0c;二是多尺度特征融合。上回我们讲过了加注意力机制&#xff0c;今天我们就来聊聊多尺度特征融合。 多尺度特征融合是一种在图像处理和CV中使用的技术&#xff0c;由…

05-Seata下SQL使用限制

不支持 SQL 嵌套不支持多表复杂 SQL(自1.6.0版本&#xff0c;MySQL支持UPDATE JOIN语句&#xff0c;详情请看不支持存储过程、触发器部分数据库不支持批量更新&#xff0c;在使用 MySQL、Mariadb、PostgreSQL9.6作为数据库时支持批量&#xff0c;批量更新方式如下以 Java 为例 …

大创项目推荐 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

网络协议与攻击模拟_09部署DHCP服务器

一、部署DHCP服务器 Windows server部署DHCP服务器 1、虚拟机网络架构理解 Vmware里面不同的虚拟机可以设置相同的Vmnet网络&#xff0c;也可以设置不同的Vmnet网络。两台虚拟机设置相同的Vmnet1网卡&#xff0c;可以看作为使用虚拟交换机将两台Vmnet1的虚拟机连接起来的。 …