设计模式:工厂方法模式

工厂模式属于创建型模式,也被称为多态工厂模式,它在创建对象时提供了一种封装机制,将实际创建对象的代码与使用代码分离,有子类决定要实例化的产品是哪一个,把产品的实例化推迟到子类。

使用场景

  • 重复代码 : 创建对象 需要使用 大量重复的代码 ;
  • 不关心创建过程 : 客户端 不依赖 产品类 , 不关心 实例 如何被创建 , 实现等细节 ;
  • 创建对象 : 一个类 通过其 子类 来 指定 创建哪个对象 ;

工厂方法模式的角色

  • 抽象产品(Product)是定义产品的接口,是工厂方法模式创建对象的父类,也就是产品对象的公共父类。
  • 产品类(ConcreteProduct)是实现了抽象产品所声明的接口,工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。
  • 抽象工厂(Factory)是工厂方法模式的核心,所有创建对象的工厂类都必须继承该接口。
  • 具体工厂(ConcreteFactory)是抽象工厂的子类,实现了抽象工厂中定义的函数,工厂方法模式所创建的每一个对象都是某个具体产品类的实例。

结构图

优缺点

优点

  • 不关心创建细节 : 用户 只需要 关心 所需产品 对应的工厂 , 无需关心创建细节 ;
  • 符合开闭原则 : 加入 新产品 , 符合开闭原则 , 提高可扩展性 ;

缺点

  • 增加复杂性:类的个数容易过多,增加系统复杂度;在添加新产品时,除了编写 新的产品类之外 ,还要 编写该产品类对应的工厂类。
  • 增加难度:增加了系统抽象性和理解难度。工厂方法本身利用了抽象,该模式中会 引入抽象层 ,如果要动态创建产品类,还要 引入反射技术。

应用实例

创建一个 Shape 接口和实现 Shape 接口的实体类。下一步是定义工厂类 ShapeFactory

FactoryPatternDemo 类使用 ShapeFactory 来获取 Shape 对象。它将向 ShapeFactory 传递信息(CIRCLE / RECTANGLE / SQUARE),以便获取它所需对象的类型。

抽象产品

java 复制代码
public interface Shape {
   void draw();
}

实现接口的产品类

java 复制代码
public class Rectangle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Rectangle::draw() method.");
   }
}



public class Square implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Square::draw() method.");
   }
}



public class Circle implements Shape {
 
   @Override
   public void draw() {
      System.out.println("Inside Circle::draw() method.");
   }
}

抽象工厂

java 复制代码
public interface Factory {
    
   public Shape getShape(String shapeType);
}

具体工厂

java 复制代码
public class ShapeFactory implements Factory {
    
   //使用 getShape 方法获取形状类型的对象
   @Override
   public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }        
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }
      return null;
   }
}

使用该工厂,通过传递类型信息来获取实体类的对象

java 复制代码
public class FactoryPatternDemo {
 
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
 
      //获取 Circle 的对象,并调用它的 draw 方法
      Shape shape1 = shapeFactory.getShape("CIRCLE");
 
      //调用 Circle 的 draw 方法
      shape1.draw();
 
      //获取 Rectangle 的对象,并调用它的 draw 方法
      Shape shape2 = shapeFactory.getShape("RECTANGLE");
 
      //调用 Rectangle 的 draw 方法
      shape2.draw();
 
      //获取 Square 的对象,并调用它的 draw 方法
      Shape shape3 = shapeFactory.getShape("SQUARE");
 
      //调用 Square 的 draw 方法
      shape3.draw();
   }
}

运行结果

java 复制代码
Inside Circle::draw() method.
Inside Rectangle::draw() method.
Inside Square::draw() method.
相关推荐
凯子坚持 c10 分钟前
Docker LXC深度解析:从基础概念到实战演练
java·开发语言
m0_7482336417 分钟前
【C++篇】C++11入门:踏入C++新世界的大门
java·c++·算法
SWUT胖虎29 分钟前
ArkTS 中 @State 底层原理详解
java·list·harmonyos·鸿蒙
SimonKing32 分钟前
【开发者必备】Spring Boot 2.7.x:WebMvcConfigurer配置手册来了(四)!
java·后端·程序员
BAGAE36 分钟前
HTTPS 加密原理介绍
java·c++·websocket·http·均值算法·启发式算法·最小二乘法
这周也會开心39 分钟前
SpringBoot的搭建方式
java·spring boot·后端
sun༒1 小时前
递归经典例题
java·算法
小年糕是糕手1 小时前
【C语言】函数栈帧的创建和销毁
java·c语言·开发语言·数据结构·c++·链表
努力努力再努力wz1 小时前
【Linux进阶系列】:信号(下)
java·linux·运维·服务器·开发语言·数据结构·c++
m0_748233642 小时前
C++与Python:内存管理与指针的对比
java·c++·python