设计模式之创建型模式(二)工厂模式

151 阅读3分钟

有哪些创建型模式

1.单例模式 2.工厂模式 3.原型模式 4.建造者模式

接下来针对以上4种设计模式进行单独讲解

2 工厂模式

2.1 定义

工厂模式中工厂类可以根据客户端参数不同返回不同的实例对象,被创建的对象都具有共同的父类。将类的创建延迟到了子类当中

2.2 应用场景

各个子类有共同的方法,同时客户端只关注该子类的使用,并不关心该子类的创建过程。工厂封装类该子类的创建过程,客户端只需要调用该工厂告诉工厂需要的子类即可

2.3 UML图

image.png

从该UML中可以看出,factory为工厂类,提供工厂方法.直接被外界调用创建所需要的子类对象,注意该工厂方法返回值为Product对象 product为抽象产品,是工厂类所创建的对象的父类,封装了产品对象的共有方法 concreateProduct为具体要定义的子类

2.4 具体代码实现

以下代码是一个针对图形的简单工厂模式,有圆形和长方形两个具体的实现类,客户端代码可以通过ShapeFactory获取所需形状类型的对象,并调用该对象的操作

interface Shape {  
   void draw();  
}  
  
// 实现接口的具体类  
class Circle implements Shape {  
   @Override  
   public void draw() {  
      System.out.println("Inside draw method of Circle");  
   }  
}  
  
class Rectangle implements Shape {  
   @Override  
   public void draw() {  
      System.out.println("Inside draw method of Rectangle");  
   }  
}  
  
// 工厂类  
class ShapeFactory {  
   // 通过getShape方法获取形状类型的对象  
   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();  
      }  
      return null;  
   }  
}  
  
// 客户端代码  
public class FactoryPatternDemo {  
   public static void main(String[] args) {  
      ShapeFactory shapeFactory = new ShapeFactory();  
  
      // 获取 Circle 的对象,并调用它的 draw 方法  
      Shape shape1 = shapeFactory.getShape("CIRCLE");  
      shape1.draw();  
  
      // 获取 Rectangle 的对象,并调用它的 draw 方法  
      Shape shape2 = shapeFactory.getShape("RECTANGLE");  
      shape2.draw();  
  
      // 获取 Circle 的对象,并调用它的 draw 方法  
      Shape shape3 = shapeFactory.getShape("CIRCLE");  
      shape3.draw();  
   }  
}

2.5 代码解析

客户端只需要调用Factory类的getProduct方法,传入要创建的对象的类型,在工厂方法中即可创建该子类的对象,由于各子类都实现了Product类,所以Factory的getProduct方法只需要返回Product类即可

2.6 代码缺点分析

当要加入新产品时,需要不断的对工厂类进行修改,需要对该模式进行改进

2.7 改进手段

2.7.1 工厂方法模式

所谓的工厂方法模式是指对上述工厂模式中工厂类再进行抽象,将工厂类定义为抽象类,对每个子类建立自己对应的具体工厂其UML如下所示

image.png 对比之前工厂模式,多了一个ConcreteFactory类,该类负责对ConcreteProduct的创建工作,以后新增一个子类,那么对应增加一个ConcreteFactory

具体改进后图形工厂代码如下所示


复制代码
// 接口  
interface Shape {  
   void draw();  
}  
  
// 实现接口的具体类  
class Circle implements Shape {  
   @Override  
   public void draw() {  
      System.out.println("Inside draw method of Circle");  
   }  
}  
  
class Rectangle implements Shape {  
   @Override  
   public void draw() {  
      System.out.println("Inside draw method of Rectangle");  
   }  
}  
  
// 抽象工厂类  
interface ShapeFactory {  
   Shape getShape(String shapeType);  
}  
  
// 具体工厂类1  
class CircleFactory implements ShapeFactory {  
   // 通过getShape方法获取圆形对象  
   @Override  
   public Shape getShape(String shapeType) {  
      if (shapeType == null) {  
         return null;  
      }        
      if (shapeType.equalsIgnoreCase("CIRCLE")) {  
         return new Circle();  
      } else {  
         return null;  
      }  
   }  
}  
  
// 具体工厂类2  
class RectangleFactory implements ShapeFactory {  
   // 通过getShape方法获取矩形对象  
   @Override  
   public Shape getShape(String shapeType) {  
      if (shapeType == null) {  
         return null;  
      }        
      if (shapeType.equalsIgnoreCase("RECTANGLE")) {  
         return new Rectangle();  
      } else {  
         return null;  
      }  
   }  
}  
  
// 客户端代码  
public class FactoryPatternDemo {  
   public static void main(String[] args) {  
      // 使用圆形工厂获取圆形对象,并调用它的 draw 方法  
      ShapeFactory circleFactory = new CircleFactory();  
      Shape shape1 = circleFactory.getShape("CIRCLE");  
      shape1.draw();  
  
      // 使用矩形工厂获取矩形对象,并调用它的 draw 方法  
      ShapeFactory rectangleFactory = new RectangleFactory();  
      Shape shape2 = rectangleFactory.getShape("RECTANGLE");  
      shape2.draw(); 
   }  
}