深入剖析Java工厂模式让你的代码更灵活
作者:陈书予 发布时间:2022-05-26 00:42:28
一、概述
1.1 什么是Java工厂模式
Java工厂模式是一种创建对象的设计模式,它提供了一种方法,通过该方法可以在不暴露对象创建逻辑的情况下,将对象的创建委托给子类或者其他对象。工厂模式可以隐藏对象的创建细节,提高了代码的可维护性、可扩展性和可重用性。
工厂模式主要有三种类型:简单工厂、工厂方法和抽象工厂。这三种类型的工厂模式各有优缺点,在不同的场景下有不同的应用。
二、简单工厂
2.1 什么是简单工厂
简单工厂模式是一种创建对象的工厂模式,它定义了一个工厂类,该工厂类根据传递的参数来决定创建哪种类型的对象。简单工厂模式适用于创建的对象比较少,且客户端只需要知道创建对象的参数。
2.2 示例代码
//抽象产品类
interface Product {
void show();
}
//具体产品类A
class ConcreteProductA implements Product {
public void show() {
System.out.println("This is product A");
}
}
//具体产品类B
class ConcreteProductB implements Product {
public void show() {
System.out.println("This is product B");
}
}
//工厂类
class SimpleFactory {
public static Product createProduct(String type) {
Product product = null;
if (type.equals("A")) {
product = new ConcreteProductA();
} else if (type.equals("B")) {
product = new ConcreteProductB();
}
return product;
}
}
//客户端
public class Client {
public static void main(String[] args) {
Product productA = SimpleFactory.createProduct("A");
productA.show();
Product productB = SimpleFactory.createProduct("B");
productB.show();
}
}
2.3 优点和缺点
简单工厂模式的优点是可以隐藏产品的创建细节,客户端不需要知道产品的创建过程,只需要传递相应的参数即可得到想要的产品。简单工厂模式可以使客户端和产品类解耦,提高代码的可维护性和可扩展性。
简单工厂模式的缺点是当需要新增产品时,需要修改工厂类的代码,这违反了开闭原则。另外,简单工厂模式通常只有一个工厂类,如果产品种类较多,工厂类的代码会变得比较臃肿,不易于维护。
三、工厂方法
3.1 什么是工厂方法
工厂方法模式是一种创建对象的工厂模式,它定义了一个抽象工厂类,该抽象工厂类有一个工厂方法,该工厂方法返回一个产品对象。具体的产品对象由实现该抽象工厂类的子类来创建,这样每个具体工厂类只负责创建特定的产品对象,从而将客户端和具体产品解耦。
工厂方法模式通常包括四个角色:抽象产品类、具体产品类、抽象工厂类和具体工厂类。
3.2 示例代码
//抽象产品类
interface Product {
void show();
}
//具体产品类A
class ConcreteProductA implements Product {
public void show() {
System.out.println("This is product A");
}
}
//具体产品类B
class ConcreteProductB implements Product {
public void show() {
System.out.println("This is product B");
}
}
//抽象工厂类
interface Factory {
Product createProduct();
}
//具体工厂类A
class ConcreteFactoryA implements Factory {
public Product createProduct() {
return new ConcreteProductA();
}
}
//具体工厂类B
class ConcreteFactoryB implements Factory {
public Product createProduct() {
return new ConcreteProductB();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product productA = factoryA.createProduct();
productA.show();
Factory factoryB = new ConcreteFactoryB();
Product productB = factoryB.createProduct();
productB.show();
}
}
3.3 优点和缺点
工厂方法模式的优点是可以将客户端和具体产品解耦,每个具体工厂类只负责创建特定的产品对象,从而使系统更加灵活、可扩展和易于维护。工厂方法模式遵循了开闭原则,当需要新增产品时,只需要添加相应的具体产品类和具体工厂类即可,而不需要修改抽象工厂类和客户端代码。
工厂方法模式的缺点是如果需要创建的产品对象比较多,就需要创建相应的具体工厂类,这会导致系统中类的个数增加,增加了系统的复杂度。另外,由于每个具体工厂类只能创建特定的产品对象,如果需要创建的产品对象较为复杂,可能需要创建多个具体工厂类来创建这些产品对象,这会导致代码的重复和冗余。
四、抽象工厂
4.1 什么是抽象工厂
抽象工厂模式是一种创建对象的工厂模式,它可以创建一组相关或相互依赖的对象,而无需指定它们的具体类。在抽象工厂模式中,有一个抽象工厂类,它定义了一些方法用于创建一组产品对象,每个方法对应一种产品。具体工厂类实现了这些方法,用于创建具体的产品对象。
抽象工厂模式通常包括四个角色:抽象产品类、具体产品类、抽象工厂类和具体工厂类。
4.2 示例代码
//抽象产品类1
interface Product1 {
void show();
}
//具体产品类1A
class ConcreteProduct1A implements Product1 {
public void show() {
System.out.println("This is product 1A");
}
}
//具体产品类1B
class ConcreteProduct1B implements Product1 {
public void show() {
System.out.println("This is product 1B");
}
}
//抽象产品类2
interface Product2 {
void show();
}
//具体产品类2A
class ConcreteProduct2A implements Product2 {
public void show() {
System.out.println("This is product 2A");
}
}
//具体产品类2B
class ConcreteProduct2B implements Product2 {
public void show() {
System.out.println("This is product 2B");
}
}
//抽象工厂类
interface Factory {
Product1 createProduct1();
Product2 createProduct2();
}
//具体工厂类A
class ConcreteFactoryA implements Factory {
public Product1 createProduct1() {
return new ConcreteProduct1A();
}
public Product2 createProduct2() {
return new ConcreteProduct2A();
}
}
//具体工厂类B
class ConcreteFactoryB implements Factory {
public Product1 createProduct1() {
return new ConcreteProduct1B();
}
public Product2 createProduct2() {
return new ConcreteProduct2B();
}
}
//客户端
public class Client {
public static void main(String[] args) {
Factory factoryA = new ConcreteFactoryA();
Product1 product1A = factoryA.createProduct1();
Product2 product2A = factoryA.createProduct2();
product1A.show();
product2A.show();
Factory factoryB = new ConcreteFactoryB();
Product1 product1B = factoryB.createProduct1();
Product2 product2B = factoryB.createProduct2();
product1B.show();
product2B.show();
}
}
4.3 优点和缺点
抽象工厂模式的优点是它可以创建一组相关或相互依赖的对象,而无需指定它们的具体类,从而使系统更加灵活、可扩展和易于维护。抽象工厂模式遵循了开闭原则,当需要新增产品时,只需要添加相应的抽象产品类、具体产品类和具体工厂类即可,不需要修改已有代码,这样可以减少系统的维护成本和风险。
抽象工厂模式还可以实现产品族的概念,即一组位于不同产品等级结构中、功能相关联的产品组成的家族,例如不同品牌的汽车,它们都有轮胎、发动机、座椅等共同特点,但具体实现各不相同。使用抽象工厂模式可以将不同品牌的汽车组成一个产品族,实现同一功能的产品可以进行互换。
抽象工厂模式的缺点是抽象工厂类需要定义一组方法用于创建产品对象,增加新产品对象时,需要修改抽象工厂类及其所有的具体工厂类,这将导致系统的维护复杂度增加。抽象工厂模式将一组相关的产品对象集合在一起创建,当产品族中的产品等级结构发生变化时,将会影响到整个系统,需要重构整个工厂。
4.4 使用工厂模式的例子
一个常见的使用抽象工厂模式的例子是操作系统的界面风格,例如Windows系统有Aero和Classic两种界面风格,而Mac OS有Aqua和Metal两种界面风格。每种界面风格都有自己的按钮、文本框、滚动条等组件,因此可以将每种界面风格看作一个产品族,而每个组件则看作产品等级结构中的一个产品。使用抽象工厂模式可以将不同界面风格的组件组成一个产品族,实现同一功能的组件可以进行互换。例如,用户可以选择使用Aero风格的按钮和Metal风格的文本框,而系统仍然能够正常工作。
另一个使用抽象工厂模式的例子是游戏中的角色创建,例如一个RPG游戏中有魔法师、战士和弓箭手三种角色,而每种角色又可以选择不同的装备,例如不同的武器、防具和饰品。可以将每种角色看作一个产品族,而每个装备则看作产品等级结构中的一个产品。使用抽象工厂模式可以将不同角色的装备组成一个产品族,实现同一功能的装备可以进行互换。例如,魔法师可以选择使用火属性的魔杖和光属性的魔法书,而战士可以选择使用铁剑和钢盾,而系统仍然能够正常工作。
来源:https://juejin.cn/post/7229891190899785765
猜你喜欢
- 自从使用 HttpClient 和 Jsoup 配合编写了几个简单的入门爬虫之后,发现对于绝对路径的需求是很频繁的,因为大部分的网页都写相对
- 目标依赖<!-- poi工具类--> <dependency>
- 一. 概述参考开源项目https://github.com/xkcoding/spring-boot-demo在系统运维中, 有时候为了避免
- 简介optional类是java8中引入的针对NPE问题的一种优美处理方式,源码作者也希望以此替代null。历史1965年,英国一位名为To
- 在本次项目中,由于时间紧张直接使用DWR做Ajax请求!要求的是动态展示,那就需要使用DWR轮询请求,但是需要做异常情况下的一些处理!特别是
- 上一小节简单分析了directArena内存分配大概流程 ,知道其先命中缓存, 如果命中不到, 则区分配一款连续内存, 这一小节带
- 本文实例为大家分享了用JavaMail发送HTML模板邮件的具体代码,供大家参考,具体内容如下依赖<dependency>&nb
- 我们讲一下Criteria查询,这个对于不是太熟悉SQL语句的我们这些程序员来说是很容易上手的。 废话不多说,看一下例子:&nbs
- 假设目录结构是maven标准结构-src-target-test.jar(你需要更新的jar包)package com.foo.common
- 本文实例讲述了java在网页上面抓取邮件地址的方法。分享给大家供大家参考。具体实现方法如下:import java.io.BufferedR
- Spring框架是一个优秀的多层J2EE系统框架,Spring本身没有提供对系统的安全性支持。Acegi是基于Spring IOC 和 AO
- 因为某个项目需要,为团队其他兄弟姐妹开发了一个 XML 分析处理器,并将其设计为一个类库,提供相应的 API 接口。为了方便大家的使用,需要
- 今天有同事用swagger2开发时,有一方法返回Map<String,List<Object>>出现无法解析错误。P
- 本文实例讲述了Java Web项目部署在Tomcat运行出错与解决方法。分享给大家供大家参考,具体如下:1、在部署Java Web项目的过程
- 没有用Java写过程序,做为一个Java新手,在写第一个Hello,world程序之前,先在Ubuntu中搭建Java开发环境。一、JDK安
- 因为公司业务需要,需要把性能日志和业务日志分开打印,用elk收集处理,所以需要对不同的业务的日志,打印到不同文件。使用的是spring bo
- 一、写在前面数据结构中的队列应该是比较熟悉的了,就是先进先出,因为有序故得名队列,就如同排队嘛,在对尾插入新的节点,在对首删除节点.jdk集
- 一个项目中需要使用两个数据库,Oracle 和Mysql,于是参考各个blog,实现此功能。写好后才发现,原来的事务失效了,我去...spr
- 基于创蓝253短信服务平台的Java调用短信接口APIpackage com.bcloud.msg.http;import java.io.
- Redis中opsForValue()方法的使用1、set(K key, V value)新增一个字符串类型的值,key是键,value是值