当前位置: 首页 > news >正文

23种设计模式--#1工厂模式

目录

 一、什么是工厂模式

二、工厂模式的类型

三、简单工厂模式

四、工厂方法模式

五、抽象工厂模式 

六、总结

 一、什么是工厂模式

        工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的方式,使得创建对象的过程与使用对象的过程分离。通过使用工厂模式,可以将对象的创建逻辑封装在一个工厂类中,而不是在客户端代码中直接实例化对象,这样可以提高代码的可维护性和可扩展性。

二、工厂模式的类型

1、简单工厂模式(Simple Factory Pattern)

  • 简单工厂模式不是一个正式的设计模式,但它是工厂模式的基础。它使用一个单独的工厂类来创建不同的对象,根据传入的参数决定创建哪种类型的对象。

2、工厂方法模式(Factory Method Pattern)

  • 工厂方法模式定义了一个创建对象的接口,但由子类决定实例化哪个类。工厂方法将对象的创建延迟到子类。

3、抽象工厂模式(Abstract Factory Pattern)

  • 抽象工厂模式提供一个创建一系列相关或互相依赖对象的接口,而无需指定它们具体的类。

三、简单工厂模式

介绍
        简单工厂模式是工厂模式的基础版本,它定义了一个工厂类来创建产品对象,客户端只需通过参数指定产品类型,无需关心具体创建逻辑。简单工厂模式不属于 GoF 23 种设计模式,但它是理解工厂模式的基础。

优点

实现简单,只需一个工厂类即可创建所有产品。
客户端与具体产品解耦,只需依赖工厂类和抽象产品接口。

缺点

工厂类职责过重,违反单一职责原则。
扩展性差,新增产品需修改工厂类代码,违反开闭原则。 

适用场景:产品种类较少且创建逻辑简单。客户端只需知道产品类型参数,不关心具体实现。

案例:实现一个披萨店,根据用户需求创建不同类型的披萨。

// 产品接口:披萨
interface Pizza {void prepare();void bake();void cut();void box();
}// 具体产品:芝士披萨
class CheesePizza implements Pizza {@Overridepublic void prepare() {System.out.println("准备芝士披萨:准备面团、番茄酱、芝士");}@Overridepublic void bake() {System.out.println("烘烤芝士披萨:180度烤20分钟");}@Overridepublic void cut() {System.out.println("切割芝士披萨:切成8块");}@Overridepublic void box() {System.out.println("包装芝士披萨:放入芝士披萨专用盒");}
}// 具体产品:蔬菜披萨
class VeggiePizza implements Pizza {@Overridepublic void prepare() {System.out.println("准备蔬菜披萨:准备面团、番茄酱、蔬菜");}@Overridepublic void bake() {System.out.println("烘烤蔬菜披萨:190度烤18分钟");}@Overridepublic void cut() {System.out.println("切割蔬菜披萨:切成6块");}@Overridepublic void box() {System.out.println("包装蔬菜披萨:放入蔬菜披萨专用盒");}
}// 简单工厂类
class SimplePizzaFactory {public static Pizza createPizza(String type) {return switch (type) {case "cheese" -> new CheesePizza();case "veggie" -> new VeggiePizza();default -> throw new IllegalArgumentException("不支持的披萨类型:" + type);};}
}// 客户端:披萨店
class PizzaStore {public Pizza orderPizza(String type) {Pizza pizza = SimplePizzaFactory.createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}
}// 测试代码
public class SimpleFactoryDemo {public static void main(String[] args) {PizzaStore store = new PizzaStore();store.orderPizza("cheese");System.out.println("-------------------");store.orderPizza("veggie");}
}

Pizza 接口定义了披萨的制作流程(准备、烘烤、切割、包装);CheesePizza 和 VeggiePizza 是具体产品,实现了披萨的制作细节;SimplePizzaFactory 是简单工厂,根据类型创建对应的披萨;PizzaStore 是客户端,依赖工厂创建披萨,不需要了解具体实现。

四、工厂方法模式

介绍
        工厂方法模式将对象的创建延迟到子类中进行,定义了一个创建对象的接口(工厂方法),由具体子类决定实例化哪个类。它属于 GoF 23 种设计模式,是简单工厂的升级版本。

优点

符合开闭原则:新增产品只需添加新的具体工厂类,无需修改现有代码。
符合单一职责原则:每个具体工厂类只负责创建一种产品。
子类可以灵活决定如何创建产品。

缺点

类的数量可能过多,增加系统复杂度。
客户端需要知道具体工厂类,增加使用难度。

适用场景

产品种类较多,且未来可能频繁新增产品。
父类(抽象工厂)无法预知具体产品类型,需由子类决定。

案例:披萨店 franchise 模式,不同地区的加盟店可以制作当地特色披萨。

// 产品接口:披萨
interface Pizza {void prepare();void bake();void cut();void box();
}// 具体产品:纽约芝士披萨
class NYStyleCheesePizza implements Pizza {@Overridepublic void prepare() {System.out.println("纽约风格芝士披萨:薄饼、马苏里拉芝士、新鲜番茄酱");}@Overridepublic void bake() {System.out.println("高温烘烤10分钟");}@Overridepublic void cut() {System.out.println("切成三角形");}@Overridepublic void box() {System.out.println("放入纽约风格披萨盒");}
}// 具体产品:芝加哥芝士披萨
class ChicagoStyleCheesePizza implements Pizza {@Overridepublic void prepare() {System.out.println("芝加哥风格芝士披萨:厚饼、意大利干酪、李子番茄酱");}@Overridepublic void bake() {System.out.println("低温烘烤30分钟");}@Overridepublic void cut() {System.out.println("切成正方形");}@Overridepublic void box() {System.out.println("放入深盘披萨专用盒");}
}// 抽象工厂类:披萨店
abstract class PizzaStore {// 工厂方法,由子类实现protected abstract Pizza createPizza(String type);public Pizza orderPizza(String type) {Pizza pizza = createPizza(type);pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}
}// 具体工厂:纽约披萨店
class NYPizzaStore extends PizzaStore {@Overrideprotected Pizza createPizza(String type) {return switch (type) {case "cheese" -> new NYStyleCheesePizza();default -> throw new IllegalArgumentException("纽约店不支持的披萨类型:" + type);};}
}// 具体工厂:芝加哥披萨店
class ChicagoPizzaStore extends PizzaStore {@Overrideprotected Pizza createPizza(String type) {return switch (type) {case "cheese" -> new ChicagoStyleCheesePizza();default -> throw new IllegalArgumentException("芝加哥店不支持的披萨类型:" + type);};}
}// 测试代码
public class FactoryMethodDemo {public static void main(String[] args) {PizzaStore nyStore = new NYPizzaStore();PizzaStore chicagoStore = new ChicagoPizzaStore();System.out.println("顾客在纽约店订购芝士披萨:");nyStore.orderPizza("cheese");System.out.println("\n顾客在芝加哥店订购芝士披萨:");chicagoStore.orderPizza("cheese");}
}

Pizza 接口和具体产品类保持不变

PizzaStore 成为抽象工厂,定义了抽象的 createPizza 方法

NYPizzaStore 和 ChicagoPizzaStore 是具体工厂,各自实现 createPizza 方法创建本地特色披萨

客户端通过不同的工厂子类创建不同风格的披萨,遵循开闭原则

五、抽象工厂模式 

介绍
抽象工厂模式提供一个创建一系列相关或相互依赖对象的接口,无需指定它们具体的类。它属于 GoF 23 种设计模式,是工厂方法模式的扩展,适用于创建产品族(一组相关产品)的场景。

优点

隔离具体实现:客户端只依赖抽象接口,无需关心具体产品类。
便于切换产品族:只需更换具体工厂类,即可切换整个产品族。
符合开闭原则:新增产品族只需添加新的具体工厂类。

缺点

难以支持新增产品类型:若需新增产品,需修改抽象工厂接口及所有具体工厂类,违反开闭原则。
实现复杂:需设计多层抽象接口和多个具体工厂类。

适用场景

系统需要独立于产品的创建、组合和表示。
产品族中的多个产品需配合使用,且需强制约束它们的一致性。

举例:披萨店需要使用不同的原料,每个地区的原料有自己的特色。

// 原料接口:面团
interface Dough {String getDescription();
}// 原料接口:酱料
interface Sauce {String getDescription();
}// 纽约原料:薄饼面团
class ThinCrustDough implements Dough {@Overridepublic String getDescription() {return "薄饼面团";}
}// 纽约原料:新鲜番茄酱
class MarinaraSauce implements Sauce {@Overridepublic String getDescription() {return "新鲜番茄酱";}
}// 芝加哥原料:厚饼面团
class ThickCrustDough implements Dough {@Overridepublic String getDescription() {return "厚饼面团";}
}// 芝加哥原料:李子番茄酱
class PlumTomatoSauce implements Sauce {@Overridepublic String getDescription() {return "李子番茄酱";}
}// 抽象工厂:原料工厂
interface PizzaIngredientFactory {Dough createDough();Sauce createSauce();
}// 具体工厂:纽约原料工厂
class NYPizzaIngredientFactory implements PizzaIngredientFactory {@Overridepublic Dough createDough() {return new ThinCrustDough();}@Overridepublic Sauce createSauce() {return new MarinaraSauce();}
}// 具体工厂:芝加哥原料工厂
class ChicagoPizzaIngredientFactory implements PizzaIngredientFactory {@Overridepublic Dough createDough() {return new ThickCrustDough();}@Overridepublic Sauce createSauce() {return new PlumTomatoSauce();}
}// 产品抽象类:披萨
abstract class Pizza {String name;Dough dough;Sauce sauce;// 准备过程依赖原料工厂abstract void prepare();void bake() {System.out.println("烘烤25分钟");}void cut() {System.out.println("切割披萨");}void box() {System.out.println("包装披萨");}public String getName() {return name;}public String toString() {return "制作完成: " + name + "\n面团: " + dough.getDescription() + "\n酱料: " + sauce.getDescription();}
}// 具体产品:纽约芝士披萨
class NYStyleCheesePizza extends Pizza {PizzaIngredientFactory ingredientFactory;public NYStyleCheesePizza(PizzaIngredientFactory ingredientFactory) {this.ingredientFactory = ingredientFactory;name = "纽约风格芝士披萨";}@Overridevoid prepare() {System.out.println("准备 " + name);dough = ingredientFactory.createDough();sauce = ingredientFactory.createSauce();}
}// 具体产品:芝加哥芝士披萨
class ChicagoStyleCheesePizza extends Pizza {PizzaIngredientFactory ingredientFactory;public ChicagoStyleCheesePizza(PizzaIngredientFactory ingredientFactory) {this.ingredientFactory = ingredientFactory;name = "芝加哥风格芝士披萨";}@Overridevoid prepare() {System.out.println("准备 " + name);dough = ingredientFactory.createDough();sauce = ingredientFactory.createSauce();}@Overridevoid cut() {System.out.println("将披萨切成正方形");}
}// 抽象工厂:披萨店
abstract class PizzaStore {// 工厂方法,由子类实现protected abstract Pizza createPizza(String type);public Pizza orderPizza(String type) {Pizza pizza = createPizza(type);System.out.println("--- 制作 " + pizza.getName() + " ---");pizza.prepare();pizza.bake();pizza.cut();pizza.box();return pizza;}
}// 具体工厂:纽约披萨店
class NYPizzaStore extends PizzaStore {@Overrideprotected Pizza createPizza(String type) {Pizza pizza = null;PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();switch (type) {case "cheese":pizza = new NYStyleCheesePizza(ingredientFactory);break;default:throw new IllegalArgumentException("纽约店不支持的披萨类型:" + type);}return pizza;}
}// 具体工厂:芝加哥披萨店
class ChicagoPizzaStore extends PizzaStore {@Overrideprotected Pizza createPizza(String type) {Pizza pizza = null;PizzaIngredientFactory ingredientFactory = new ChicagoPizzaIngredientFactory();switch (type) {case "cheese":pizza = new ChicagoStyleCheesePizza(ingredientFactory);break;default:throw new IllegalArgumentException("芝加哥店不支持的披萨类型:" + type);}return pizza;}
}// 测试代码
public class AbstractFactoryDemo {public static void main(String[] args) {PizzaStore nyStore = new NYPizzaStore();PizzaStore chicagoStore = new ChicagoPizzaStore();System.out.println("顾客在纽约店订购芝士披萨:");Pizza nyCheese = nyStore.orderPizza("cheese");System.out.println(nyCheese);System.out.println("\n顾客在芝加哥店订购芝士披萨:");Pizza chicagoCheese = chicagoStore.orderPizza("cheese");System.out.println(chicagoCheese);}
}

六、总结

        工厂模式是一种创建型设计模式,其核心思想是将对象的创建与使用分离,通过工厂类或接口来封装对象的创建逻辑。它解决了以下问题:

  • 降低代码耦合度:客户端无需依赖具体产品类,只需依赖抽象接口。
  • 提高可维护性:创建逻辑集中在工厂,便于修改和扩展。
  • 遵循设计原则:符合开闭原则(对扩展开放,对修改关闭)和单一职责原则。

简单工厂是基础,适合简单场景,但扩展性差。

工厂方法通过子类解耦产品创建,解决了简单工厂的扩展性问题,适用于单一产品的多变体场景。

抽象工厂进一步抽象,管理一组相关产品,解决了产品族的一致性问题,但实现复杂度更高。


文章转载自:
http://chinky.isnyv.cn
http://carbonic.isnyv.cn
http://bremerhaven.isnyv.cn
http://beck.isnyv.cn
http://chimera.isnyv.cn
http://brugge.isnyv.cn
http://acrawl.isnyv.cn
http://beneficed.isnyv.cn
http://chalicothere.isnyv.cn
http://bespread.isnyv.cn
http://areometry.isnyv.cn
http://bedell.isnyv.cn
http://chevy.isnyv.cn
http://aquifer.isnyv.cn
http://aggiornamento.isnyv.cn
http://affectlessness.isnyv.cn
http://audit.isnyv.cn
http://acidity.isnyv.cn
http://carbonyl.isnyv.cn
http://barrier.isnyv.cn
http://accompt.isnyv.cn
http://berceau.isnyv.cn
http://breakpoint.isnyv.cn
http://aerobics.isnyv.cn
http://blanche.isnyv.cn
http://cheapie.isnyv.cn
http://baldheaded.isnyv.cn
http://chic.isnyv.cn
http://bef.isnyv.cn
http://abecedarian.isnyv.cn
http://www.dtcms.com/a/281013.html

相关文章:

  • 运维打铁: 软件定义网络(SDN)的实践应用
  • tun2socks原理浅析
  • 在新闻资讯 APP 中添加不同新闻分类页面,通过 ViewPager2 实现滑动切换
  • 【LeetCode 热题 100】226. 翻转二叉树——DFS
  • Halcon双相机单标定板标定实现拼图
  • 野卡恢复运营?关服已成趋势
  • 路由器的核心原理以及作用
  • 某东 jdgs参数unidbg环境检测patch分析
  • 健康监测的微泰医疗的公司创始人背景、股权构成、产品类型及技术能力的全方位解读
  • 腾讯元器开发流程解析
  • Enhancing Input-Label Mapping in In-Context Learning withContrastive Decoding
  • 每日钉钉API探索:chooseUserFromList灵活选取自定义联系人
  • 基于 p5.js 实现的未来感神经网络可视化特效
  • Jupyer 魔法方法
  • 专题 函数闭包
  • 海狸IM - 一个功能完整的开源即时通讯系统
  • 数据库中索引到底对哪些sql操作具有提速作用?
  • Python 模块导入常见错误及解决方法
  • 公网ip到服务器流程
  • 智慧水务平台,智慧水务,惠及民生,提升水务管理效率与服务质量
  • 开发者工具在爬虫开发中的应用与面板功能详解
  • kiro, 新款 AI 编辑器, 简单了解一下
  • 图机器学习(5)——无监督图学习与浅层嵌入方法
  • AI Agent概念是什么?全文探讨智能体概念、技术原理及未来趋势
  • 心理学IP的长效增长逻辑:专业壁垒与信任生态的共生之道
  • Python并发模型:多线程与多进程的优劣对比与实战应用
  • linux-线程互斥
  • SMTPman,smtp发送邮件服务器助力邮件通信
  • 对于MSPM0G3系列的使用
  • 【make工具】在Windows环境安装