java设计模式 工厂,Java 设计模式——工厂模式

本文详细介绍了Java设计模式中的工厂模式,包括简单工厂、工厂方法和抽象工厂三种模式。通过示例代码展示了每种模式的应用场景及优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

d951ac56136e

image

前言

最近在复习java设计模式中的工厂模式。本来有一点小小的理解。感觉都写的不错,就是有点太零散了,最后还是决定自己手写一把,加深印象。顺便做个总结,以后复习起来也方便许多。

一、简介

目前从网上了解工厂模式大体分为简单工厂、工厂方法、抽象工厂等三种模式。工厂方法模式也可称为工厂模式,与抽象模式都是属于GOF23种设计模式中的一员。可以大概理解为:简单工厂进阶变成了工厂方法,然后再进阶成了抽象工厂。难度逐步增加,也越来越抽象。下面按先易到难逐个分析。

二、简单工厂模式

属于创建型模式,又叫做静态工厂方法模式,不属于23种GOF设计模式之一。是由一个工厂对象决定创建出哪一种产品类的实例。实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。

作用:将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。

主要角色

工厂:负责实现创建所有实例的内部逻辑,并提供一个外界调用的方法,创建所需的产品对象。

抽象产品:负责描述产品的公共接口

具体产品:描述生产的具体产品。

举个简单易懂的例子:

“假设”有一台饮料机(工厂),可以调出各种口味的饮料(抽象产品),有三个按钮(参数)对应这三种饮料(具体产品)。这时候你可以根据点击按钮来选择你喜欢的饮料。

/**

* @ Product.java

* 抽象产品

* 描述产品的公共接口

*/

abstract class Product {

//产品介绍

abstract void intro();

}

/**

* @ AProduct.java

* 具体产品A

* (可以看成是一种饮料:可乐)

*/

public class AProduct extends Product{

@Override

void intro() {

System.out.println("可乐");

}

}

/**

* @ BProduct.java

* @具体产品B

* @(可以看成是一种饮料:奶茶)

*/

public class BProduct extends Product{

@Override

void intro() {

System.out.println("奶茶");

}

}

/**

* @ CProduct.java

* 具体产品C

* (可以看成是一种饮料:咖啡)

*/

public class CProduct extends Product{

@Override

void intro() {

System.out.println("咖啡");

}

}

d951ac56136e

image.gif

Factory.java

/**

* 工厂

* 负责实现创建所有实例的内部逻辑,并提供一个外界调用的方法,创建所需的产品对象。

*/

public class Factory {

/**

* 供外界调用的方法

* (可以看成是对外提供的三种按钮)

* @param type

* @return 产品实例

*/

public static Product getProduct(String type) {

switch (type) {

case "A":

return new AProduct();

case "B":

return new BProduct();

case "C":

return new CProduct();

default:

return null;

}

}

}

d951ac56136e

image.gif

测试

public class Test {

public static void main(String[] args) {

//创建具体的工厂

Factory factory = new Factory();

//根据传入的参数生产不同的产品实例

//(按下不同的按钮,获取饮料)

Product A = Factory.getProduct("A");

A.intro();

Product B = Factory.getProduct("B");

B.intro();

Product C = Factory.getProduct("C");

C.intro();

}

}

d951ac56136e

image.gif

d951ac56136e

image

根据例子可以描述为:一个抽象产品类,可以派生出多个具体产品类。一个具体工厂类,通过往此工厂的static方法中传入不同参数,产出不同的具体产品类实例。

优点:将创建使用工作分开,不必关心类对象如何创建,实现了解耦;

缺点:违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。

三、工厂方法模式

又称工厂模式、多态工厂模式和虚拟构造器模式,通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。一种常用的对象创建型设计模式,此模式的核心精神是封装 类中不变的部分。

作用:将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。

主要角色

抽象工厂:描述具体工厂的公共接口

具体工厂:描述具体工厂,创建产品的实例,供外界调用

抽象产品:负责描述产品的公共接口

具体产品:描述生产的具体产品

举个简单易懂的例子:

“假设”有各类的饮料机(抽象工厂),可以调出各种的饮料(抽象产品)。但是一类饮料机(具体工厂),只能生产一种饮料(具体产品)。如果你需要喝可乐,就需要买可乐饮料机。

产品:Product.java 、ProductA.java 、ProductB.java

/**

* @ Product.java

* 抽象产品

*/

abstract class Product {

//产品介绍

abstract void intro();

}

/**

* @ ProductA.java

* 具体产品A

*/

public class ProductA extends Product{

@Override

void intro() {

System.out.println("饮料A");

}

}

/**

* @ ProductB.java

* 具体产品B

*/

public class ProductB extends Product{

@Override

void intro() {

System.out.println("饮料B");

}

}

d951ac56136e

image.gif

工厂:Factory.java、FactoryA.java 、FactoryB.java

/**

* @ Factory.java

* 抽象工厂

*/

abstract class Factory {

//生产产品

abstract Product getProduct();

}

/**

* @ FactoryA.java

* 具体工厂A

* 负责具体的产品A生产

*/

public class FactoryA extends Factory{

@Override

Product getProduct() {

return new ProductA();

}

}

/**

* @ FactoryB.java

* @具体工厂B

* 负责具体的产品B生产

*/

public class FactoryB extends Factory{

@Override

Product getProduct() {

return new ProductB();

}

}

d951ac56136e

image.gif

测试:Test.java

public class Test {

public static void main(String[] args) {

//创建具体的工厂

FactoryA factoryA = new FactoryA();

//生产相对应的产品

factoryA.getProduct().intro();

FactoryB factoryB = new FactoryB();

factoryB.getProduct().intro();

}

}

d951ac56136e

image.gif

根据例子可以描述为:一个抽象产品类,可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。每个具体工厂类只能创建一个具体产品类的实例。

优点:

符合开-闭原则:新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可

符合单一职责原则:每个具体工厂类只负责创建对应的产品

缺点:

增加了系统的复杂度:类的个数将成对增加

增加了系统的抽象性和理解难度

一个具体工厂只能创建一种具体产品

四、抽象工厂模式

定义:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。

解决的问题:每个工厂只能创建一类产品(工厂方法模式)

抽象工厂模式与工厂方法模式最大的区别:抽象工厂中每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类

主要对象

抽象工厂:描述具体工厂的公共接口

具体工厂:描述具体工厂,创建产品的实例,供外界调用

抽象产品族:描述抽象产品的公共接口

抽象产品:描述具体产品的公共接口

具体产品:具体产品

举个简单易懂的例子:(找了个不怎么好的比喻,看不懂得可以看相关推荐链接)

“假设”有各类的自动售卖机(抽象工厂),可以出售各类食品(抽象产品族)。

有饮料、零食(抽象产品),比如常见的零食售卖机(具体工厂),出售矿泉水与面包(具体产品)。

产品:Product、ProductA、ProductB、ProductAa、ProductBb

/**

* @ Product.java

* 抽象产品族 (食品)

*/

abstract class Product {

//产品介绍

abstract void intro();

}

/**

* @ ProductA.java

* 抽象产品 (饮料)

*/

abstract class ProductA extends Product{

@Override

abstract void intro();

}

/**

* @ ProductB.java

* 抽象产品 (零食)

*/

abstract class ProductB extends Product{

@Override

abstract void intro();

}

/**

* @ ProductAa.java

* 具体产品 (矿泉水)

*/

public class ProductAa extends ProductA{

@Override

void intro() {

System.out.println("矿泉水");

}

}

/**

* @ ProductBb.java

* 抽象产品 (面包)

*/

public class ProductBb extends ProductB{

@Override

void intro() {

System.out.println("面包");

}

}

d951ac56136e

image.gif

工厂:Factory.java、FactoryA.java

/**

* @ Factory.java

* 抽象工厂

*/

abstract class Factory {

//生产饮料

abstract Product getProductA();

//生产零食

abstract Product getProductB();

}

/**

* @ FactoryA.java

* 具体工厂A

* 负责具体的A类产品生产

*/

public class FactoryA extends Factory{

@Override

Product getProductA() {

//生产矿泉水

return new ProductAa();

}

@Override

Product getProductB() {

//生产面包

return new ProductBb();

}

}

d951ac56136e

image.gif

测试:Test.java

public class Test {

public static void main(String[] args) {

//创建零食售卖机(具体工厂),

FactoryA factoryA = new FactoryA();

//获取矿泉水与面包(具体产品)

factoryA.getProductA().intro();

factoryA.getProductB().intro();

}

}

d951ac56136e

image.gif

d951ac56136e

image

d951ac56136e

image.gif

根据实例可以描述为: 多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。一个抽象工厂类,可以派生出多个具体工厂类。 每个具体工厂类可以创建多个具体产品类的实例。.

优点:

降低耦合

符合开-闭原则

符合单一职责原则

不使用静态工厂方法,可以形成基于继承的等级结构。

缺点:难以扩展新种类产品

五、总结

角色不同:

简单工厂:具体工厂、抽象产品、具体产品

工厂方法:抽象工厂、具体工厂、抽象产品、具体产品

抽象工厂:抽象工厂、具体工厂、抽象产品族、抽象产品、具体产品

定义:

简单工厂:由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(继承自一个父类或接口)的实例。

工厂方法:定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象

抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类;具体的工厂负责实现具体的产品实例。

对比:

工厂方法模式解决了简单工厂模式的“开放 - 关闭原则

抽象工厂模式解决了工厂方法模式一个具体工厂只能创建一类产品

六、Demo地址

六、参考文档

简单工厂模式

工厂方法模式

抽象工厂模式

七、内容推荐

如果你觉得我写的不错或者对您有所帮助的话。不妨顶一个(点个赞呗),也方便以后复习

您的每个举动都是对我莫大的支持

谢谢了!!!

d951ac56136e

image

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值