Java设计模式之简单工厂模式,工厂模式,抽象工厂模式

本文深入解析简单工厂模式、工厂模式及抽象工厂模式,探讨其实现步骤、优缺点及应用场景,帮助读者掌握工厂模式的设计思想。

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

设计模式之:简单工厂模式。

个人印象笔记地址:https://app.yinxiang.com/fx/a45a73de-b62f-4083-bd3e-4c0c68ce4548

1.含义:简单工厂模式又叫静态方法模式(因为工厂类定义了一个静态方法)
 
2.结果: 将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,
从而避免了在客户端代码中显式指定,实现了解耦。
 
UML图:
 
 
3.使用步骤 
  • 创建 抽象产品类 & 定义具体产品的公共接口;
  • 创建 具体产品类(继承抽象产品类) & 定义生产的具体产品;
  • 创建 工厂类,通过创建静态方法根据传入不同参数从而创建不同具体产品类的实例;
  • 外界通过调用 工厂类的静态方法传入不同参数从而创建不同 具体产品类的实例
 
4.举个栗子


步骤1. 创建抽象产品类,定义具体产品的公共接口

abstract class Product{//抽象产品类
public abstract void Show();//抽象方法
}

步骤2. 创建具体产品类(继承抽象产品类),定义生产的具体产品

class ProductA extends Product{
///定义具体产品类A

@Override
public void Show() {
System.out.println("生产出了产品A");//重写覆盖原有show()方法
}}

class ProductB extends Product{//

//定义具体产品类B

@Override
public void Show() {
System.out.println("生产出了产品C");重写覆盖原有show()方法
}}

class ProductC extends Product{
//具体产品类C

@Override
public void Show() {
System.out.println("生产出了产品C");
}}

步骤3. 创建工厂类,通过创建静态方法从而根据传入不同参数创建不同具体产品类的实例。静态方法的调用:可以直接类名.方法

class Factory {
public static Product Manufacture(String ProductName){//带参数的工厂类
//工厂类里用switch语句控制生产哪种商品;
//使用者只需要调用工厂类的静态方法就可以实现产品类的实例化。
switch (ProductName){
case "A":
return new ProductA();

case "B":
return new ProductB();

case "C":
return new ProductC();

default:
return null;

   }
 }
}

步骤4. 外界通过调用工厂类的静态方法,传入不同参数从而创建不同具体产品类的实例

//工厂产品生产流程
public class SimpleFactoryPattern {
public static void main(String[] args){
Factory mFactory = new Factory();
不用实例化具体的产品类

//客户要产品A
try {//调用工厂类的静态方法 & 传入不同参数从而创建产品实例
mFactory.Manufacture("A").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品B
try {
mFactory.Manufacture("B").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品C
try {
mFactory.Manufacture("C").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
}

//客户要产品D
try {
mFactory.Manufacture("D").Show();
}catch (NullPointerException e){
System.out.println("没有这一类产品");
  }
 }
}

结果输出:

生产出了产品A
生产出了产品C
生产出了产品C
没有这一类产品
 
 

5. 优点

  • 将创建实例的工作与使用实例的工作分开,使用者不必关心类对象如何创建,实现了解耦;
  • 把初始化实例时的工作放到工厂里进行,使代码更容易维护。 更符合面向对象的原则 & 面向接口编程,而不是面向实现编程。

6. 缺点

  • 工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
  • 违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
  • 简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构

 

设计模式之:工厂模式。

 
1.含义: 通过定义工厂父类负责定义创建对象的公共接口,而子类则负责生成具体的对象。
 

2. 使用步骤

步骤1: 创建 抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建 抽象产品类 ,定义具体产品的公共接口;
步骤3: 创建 具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤4:创建 具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤5:外界通过调用具体工厂类的方法,从而创建不同 具体产品类的实例
 
3.举个栗子
   步骤1:  创建 抽象工厂类 ,定义具体工厂的公共接口
 
abstract class Factory{

public abstract Product Manufacture();

}

步骤2: 创建抽象产品类 ,定义具体产品的公共接口;

abstract class Product{

public abstract void Show();

}

步骤3: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;

class ProductA extends Product{
//具体产品A类
@Override
public void Show() {
System.out.println("生产出了产品A");
  }
}

class ProductB extends Product{
//具体产品B类
@Override
public void Show() {
System.out.println("生产出了产品B");
  } 
}

步骤4:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;

class FactoryA extends Factory{
//工厂A类 - 生产A类产品
@Override
public Product Manufacture() {
return new ProductA();
 }
}

class FactoryB extends Factory{
//工厂B类 - 生产B类产品
@Override
public Product Manufacture() {
return new ProductB();
 }
}

步骤5:外界通过调用具体工厂类的方法,从而创建不同具体产品类的实例

public class FactoryPattern {
//生产工作流程
public static void main(String[] args){
//客户要产品A

FactoryA mFactoryA = new FactoryA();
mFactoryA.Manufacture().Show();

//客户要产品B
FactoryB mFactoryB = new FactoryB();
mFactoryB.Manufacture().Show();
  }
}
测试结果:
生产出了产品A
生产出了产品C
 
结论:

4. 优点

  • 更符合开-闭原则:新增一种产品时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
  • 符合单一职责原则:每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
  • 不使用静态工厂方法,可以形成基于继承的等级结构。
        简单工厂模式的工厂类使用静态工厂方法
 

5. 缺点

  • 添加新产品时,除了增加新产品类外,还要提供与之对应的具体工厂类, 系统类的个数将成对增加,在一定程度上增加了系统的复杂度;同时,有更多的类需要编译和运行,会给系统带来一些额外的开销;
  • 由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术 ,增加了系统的实现难度
  • 虽然保证了工厂方法内的对修改关闭,但对于使用工厂方法的类,如果要更换另外一种产品,仍然需要修改实例化的具体工厂类;
  • 一个具体工厂只能创建一种具体产品

6. 应用场景

在了解了优缺点后,我总结了工厂方法模式的应用场景:
  • 当一个类不知道它所需要的对象的类时
    在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可;
  • 当一个类希望通过其子类来指定创建对象时
    在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
  • 将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
 
 
 
结论: 工厂模式可以说是简单工厂模式的进一步抽象和拓展,在保留了简单工厂的封装优点的同时,让扩展变得简单,让继承变得可行,增加了多态性的体现。
 
 

设计模式之:抽象工厂模式。

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

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

1.2 主要作用

允许使用抽象的接口来创建一组相关产品,而不需要知道或关心实际生产出的具体产品是什么,这样就可以从具体产品中被解耦。
 

2.1使用步骤

步骤1: 创建 抽象工厂类,定义具体工厂的公共接口;
步骤2: 创建 抽象产品族类 ,定义抽象产品的公共接口;
步骤3: 创建 抽象产品类 (继承抽象产品族类),定义具体产品的公共接口;
步骤4: 创建 具体产品类(继承抽象产品类) & 定义生产的具体产品;
步骤5:创建 具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;
步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例;
 
 
3.举个栗子:
 
步骤1:  创建 抽象工厂类 ,定义具体工厂的公共接口
abstract class Factory{

public abstract Product ManufactureContainer();
public abstract Product ManufactureMould();

}

步骤2: 创建抽象产品族类 ,定义具体产品的公共接口;

abstract class AbstractProduct{

public abstract void Show();

}

步骤3: 创建抽象产品类 ,定义具体产品的公共接口

abstract class ContainerProduct extends AbstractProduct{
//容器产品抽象类
@Override
public abstract void Show();
}

abstract class MouldProduct extends AbstractProduct{
//模具产品抽象类
@Override
public abstract void Show();

}

步骤4: 创建具体产品类(继承抽象产品类), 定义生产的具体产品;

class ContainerProductA extends ContainerProduct{//容器产品A类
@Override
public void Show() {
System.out.println("生产出了容器产品A");
 }
}

class ContainerProductB extends ContainerProduct{//容器产品B类
@Override
public void Show() {
System.out.println("生产出了容器产品B");
 }
}

class MouldProductA extends MouldProduct{//模具产品A类

@Override
public void Show() {
System.out.println("生产出了模具产品A");
 }
}

class MouldProductB extends MouldProduct{//模具产品B类

@Override
public void Show() {
System.out.println("生产出了模具产品B");
 }
}

步骤5:创建具体工厂类(继承抽象工厂类),定义创建对应具体产品实例的方法;

class FactoryA extends Factory{//A厂 - 生产模具+容器产品

@Override
public Product ManufactureContainer() {
return new ContainerProductA();
}

@Override
public Product ManufactureMould() {
return new MouldProductA();
 }
}

class FactoryB extends Factory{ //B厂 - 生产模具+容器产品

@Override
public Product ManufactureContainer() {
return new ContainerProductB();
}

@Override
public Product ManufactureMould() {
return new MouldProductB();
 }
}

步骤6:客户端通过实例化具体的工厂类,并调用其创建不同目标产品的方法创建不同具体产品类的实例

public class AbstractFactoryPattern {//生产工作流程
public static void main(String[] args){

FactoryA mFactoryA = new FactoryA();
FactoryB mFactoryB = new FactoryB();
//A厂当地客户需要容器产品A
mFactoryA.ManufactureContainer().Show();
//A厂当地客户需要模具产品A
mFactoryA.ManufactureMould().Show();

//B厂当地客户需要容器产品B
mFactoryB.ManufactureContainer().Show();
//B厂当地客户需要模具产品B
mFactoryB.ManufactureMould().Show();

 }
}
结果:
生产出了容器产品A
生产出了容器产品B
生产出了模具产品A
生产出了模具产品B

4. 优点

  • 降低耦合
    抽象工厂模式将具体产品的创建延迟到具体工厂的子类中,这样将对象的创建封装起来,可以减少客户端与具体产品类之间的依赖,从而使系统耦合度低,这样更有利于后期的维护和扩展;
  • 更符合开-闭原则
    新增一种产品类时,只需要增加相应的具体产品类和相应的工厂子类即可
简单工厂模式需要修改工厂类的判断逻辑
  • 符合单一职责原则
    每个具体工厂类只负责创建对应的产品
简单工厂中的工厂类存在复杂的switch逻辑判断
  • 不使用静态工厂方法,可以形成基于继承的等级结构。
    简单工厂模式的工厂类使用静态工厂方法
     

    5. 缺点

    抽象工厂模式很难支持新种类产品的变化。
    这是因为抽象工厂接口中已经确定了可以被创建的产品集合,如果需要添加新产品,此时就必须去修改抽象工厂的接口,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。
     

    6. 应用场景

    在了解了优缺点后,我总结了工厂方法模式的应用场景:
  • 一个系统不要求依赖产品类实例如何被创建、组合和表达的表达,这点也是所有工厂模式应用的前提。
  • 这个系统有多个系列产品,而系统中只消费其中某一系列产品
  • 系统要求提供一个产品类的库,所有产品以同样的接口出现,客户端不需要依赖具体实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值