工厂模式简介

概念

工厂模式(Factory Pattern)是一种创建型设计模式,它提供了一种封装对象实例化过程的方式,客户端只需要关注接口或抽象类,并由工厂类根据具体需求返回相应的实例。工厂模式将对象的创建与使用分离,客户端无需直接调用构造函数来创建对象。工厂模式定义了一个抽象工厂和多个具体工厂,每个具体工厂负责创建特定类型的产品。

特点

  1. 封装性:隐藏了对象实例化细节,客户端只需要与抽象接口交互。
  2. 扩展性:易于添加新产品或变更现有产品的实现。
  3. 解耦性:将客户端与具体产品之间解耦,降低了代码依赖关系。

优点

  1. 符合开闭原则:新增产品时无需修改已有代码,在扩展上更加灵活。
  2. 降低耦合度:客户端仅依赖于抽象接口而非具体实现类。
  3. 高内聚、低耦合:相关逻辑被封装在各自的具体工厂中。

缺点

  1. 增加系统复杂度:引入额外的类和层级,增加了代码量。
  2. 需要额外的工厂类:每个具体产品都需要对应一个具体工厂类。

适用场景

  1. 需要创建多个相似对象的场景。
  2. 客户端不关心实例化过程和细节,只需获取抽象接口即可的场景。

实现方式

简单工厂模式

实现原理:

  1. 定义一个接口或父类来表示产品。
  2. 创建具体产品类,它们继承自父类或实现接口。
  3. 创建一个简单工厂类,该类包含一个静态方法用于根据客户端传入的参数来创建相应的具体产品对象。

实现代码:

java 复制代码
// 接口或父类
interface Product {
    void doSomething();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductA do something");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductB do something");
    }
}

// 简单工厂类
public class SimpleFactory {
    
    // 静态方法根据参数创建对应的具体产品对象
    public static Product createProduct(String type) {
        if (type.equals("A")) { 
            return new ConcreteProductA();
        } else if (type.equals("B")) { 
            return new ConcreteProductB();
        } else { 
            throw new IllegalArgumentException("Invalid product type.");
        }
    }
    
    public static void main(String[] args){
         Product a = SimpleFactory.createProduct("A");
         a.doSomething();
    }
}

上述代码中,我们定义了一个 Product 接口作为抽象基类,然后创建了两个具体产品类 ConcreteProductA 和 ConcreteProductB,它们都实现了 Product 接口。最后,我们创建了一个简单工厂类 SimpleFactory,其中的静态方法根据客户端传入的参数来创建相应的具体产品对象。使用简单工厂模式时存在以下问题:

  1. 违反开闭原则:每次添加新产品都需要修改工厂类中的代码。
  2. 工厂职责过重:所有产品的创建逻辑集中在一个工厂类中,导致该类变得庞大而复杂。

尽管简单工厂模式存在以上问题,但它仍然是一种常用且易于理解和实现的工厂模式。

工厂方法模式

实现原理:

  1. 定义一个接口或父类来表示产品。
  2. 创建具体产品类,它们继承自父类或实现接口。
  3. 创建一个抽象工厂接口,该接口声明了创建产品的方法。
  4. 创建多个具体工厂类,每个具体工厂类负责创建特定类型的产品。

实现代码:

java 复制代码
// 接口或父类
interface Product {
    void doSomething();
}

// 具体产品A
class ConcreteProductA implements Product {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductA do something");
    }
}

// 具体产品B
class ConcreteProductB implements Product {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductB do something");
    }
}

// 抽象工厂接口
interface Factory {
    Product createProduct();
}

// 具体工厂A用于创建具体产品A
class ConcreteFactoryA implements Factory {
    
    @Override
    public Product createProduct() {
        return new ConcreteProductA();
    }
}

// 具体工厂B用于创建具体产品B 
class ConcreteFactoryB implements Factory {

   @Override 
   public Product createProduct() { 
       return new ConcreteProductB();
   }
}

上述代码中,我们定义了一个 Product 接口作为抽象基类,然后创建了两个具体产品类 ConcreteProductA 和 ConcreteProductB,它们都实现了 Product 接口。接着,我们定义了一个抽象工厂接口 Factory,其中声明了一个用于创建产品的方法。最后,我们创建了两个具体工厂类 ConcreteFactoryA 和 ConcreteFactoryB,分别用于创建具体产品 A 和 B。

使用工厂方法模式时存在以下问题:

  1. 每次添加新产品需要同时增加对应的具体工厂类。
  2. 客户端需要知道不同的具体工厂类来获取不同类型的产品。

尽管存在以上问题,但工厂方法模式能够提供更好的扩展性和灵活性,并且符合开闭原则。客户端只需关注与特定的抽象工厂和产品进行交互即可。

抽象工厂模式

实现原理:

  1. 定义产品族接口,该接口声明了一组相关的产品。
  2. 创建多个具体产品族类,每个具体产品族类负责实现对应的抽象产品族接口。
  3. 定义抽象工厂接口,该接口声明了用于创建不同产品族对象的方法。
  4. 创建多个具体工厂类,每个具体工厂类负责创建特定类型的产品族对象。

实现代码:

java 复制代码
//产品A
interface ProductA {
    void doSomething();
}

// 具体产品A1
class ConcreteProductA1 implements ProductA {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductA1 do something");
    }
}

// 具体产品A2
class ConcreteProductA2 implements ProductA {
    @Override
    public void doSomething() {
        System.out.println("ConcreteProductA2 do something");
    }
}

// 抽象产品B 
interface ProductB { 
   void doSomething(); 
} 

// 具体产品B1 
class ConcreateProductB1 implements ProductB { 
   @Override 
   public void doSomething() { 
       System.out.println("ConcreteProductB1 do something"); 
   } 
} 

// 具体产品B2 
class ConcreateProductB2 implements ProductB { 
   @Override 
   public void doSomething() { 
       System.out.println("ConcreteProductB2 do something"); 
   } 
}

// 抽象工厂接口
interface AbstractFactory {
    ProductA createProductA();
    ProductB createProductB();
}

// 具体工厂1用于创建具体产品族1
class ConcreteFactory1 implements AbstractFactory {
    
    @Override
    public ProductA createProductA() {
        return new ConcreteProductA1();
    }
    
    @Override
    public ProductB createProductB() {
        return new ConcreateProductB1();
    }
}

// 具体工厂2用于创建具体产品族2
class ConcreteFactory2 implements AbstractFactory {

   @Override  
   public ProductA createProductA() {  
       return new ConcreteProductA2();  
   }  

  @Override   
  public ProductB createProductB() {   
      return new ConcreateProductB2();   
  }  
}

上述代码中,我们定义了两个产品接口 ProductA 和 Prodcut B,并分别实现了它们的具体产品类。然后,我们定义了一个抽象工厂接口 AbstractFactory,其中声明了两个方法用于创建不同类型的抽象产品对象。最后,我们创建了两个具体工厂类 ConcreteFactory1 和 ConcreteFactory2 分别负责创建特定的抽象产品族对象。

使用抽象工厂模式时存在以下问题:

  1. 每次添加新产品族需要同时增加对应的产品接口和具体产品类。
  2. 客户端需要知道不同的具体工厂类来获取不同类型的抽象产品。

尽管存在以上问题,但抽象工厂模式能够提供更好的扩展性和灵活性,并且符合开闭原则。客户端只需关注与特定的抽象工厂和产品进行交互即可。

相关推荐
c4fx2 分钟前
Delphi5利用DLL实现窗体的重用
开发语言·delphi·dll
kinlon.liu10 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
鸽芷咕26 分钟前
【Python报错已解决】ModuleNotFoundError: No module named ‘paddle‘
开发语言·python·机器学习·bug·paddle
王哲晓31 分钟前
Linux通过yum安装Docker
java·linux·docker
Jhxbdks35 分钟前
C语言中的一些小知识(二)
c语言·开发语言·笔记
java66666888835 分钟前
如何在Java中实现高效的对象映射:Dozer与MapStruct的比较与优化
java·开发语言
Violet永存36 分钟前
源码分析:LinkedList
java·开发语言
执键行天涯37 分钟前
【经验帖】JAVA中同方法,两次调用Mybatis,一次更新,一次查询,同一事务,第一次修改对第二次的可见性如何
java·数据库·mybatis
代码雕刻家38 分钟前
数据结构-3.1.栈的基本概念
c语言·开发语言·数据结构
Fan_web39 分钟前
JavaScript高级——闭包应用-自定义js模块
开发语言·前端·javascript·css·html