【一天一个设计模式】—— 抽象工厂模式(Abstract Factory Pattern)

定义:

Provide an interface for creating families of related or dependent
objects without specifying their concrete classes.

为创建一组相关或相互依赖的对象提供一个接口,而且无须指定它们的具体类。

和工厂模式一样,抽象工厂模式同样是创建型设计模式,但不同的是,抽象工厂中的每个工厂可以创建多种类的产品;而工厂方法每个工厂只能创建一类产品

举个栗子,你有一家公司,名下有一座生产矿泉水的工厂,它可以根据传入的订单号生产不同价位的矿泉水,这就是工厂模式,只能创建矿泉水一类产品。由于业务拓展,你想生产饮料类产品,经过协商,你建造了一个可以同时容纳矿泉水工厂和饮料工厂的超大工厂,而矿泉水工厂和饮料工厂又可以根据需求生产价位不同的饮品,这就是抽象工厂模式,抽象工厂中每个工厂可以创建多种类的产品。


下面通过RUNOOB中的例子来详细分析抽象工厂模式(简化形式,无AbstractProduct类)。
在这里插入图片描述
通过UML图可以很清晰的分析出抽象工厂模式的组成包括工厂生成器、抽象工厂类、工厂类、产品接口、产品接口实现类。下面通过代码分析。


代码

产品接口 – shape

public interface Shape {
   void draw();
}
------------------------
public interface Color {
   void fill();
}

产品接口shape实现类 – Rectangle、Square、Circle

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.");
   }
}

产品接口color实现类 – Red 、Green 、Blue

public class Red implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Red::fill() method.");
   }
}
-------------------------------------
public class Green implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Green::fill() method.");
   }
}
------------------------------------
public class Blue implements Color {
 
   @Override
   public void fill() {
      System.out.println("Inside Blue::fill() method.");
   }
}

抽象工厂类AbstractFactory

public abstract class AbstractFactory {
   public abstract Color getColor(String color);
   public abstract Shape getShape(String shape);
}

来看抽象工厂类,其中定义了两个抽象方法getColor()、getShape(),接下来我们就要扩展这两个抽象方法,即创建工厂类来继承抽象工厂类,根据条件生成具体的产品。

工厂类ShapeFactory

public class ShapeFactory extends AbstractFactory {
   //扩展方法,根据给定条件创建不同的产品
   @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;
   }
   
   @Override
   public Color getColor(String color) {
      return null;
   }
}

工厂类ColorFactory

public class ColorFactory extends AbstractFactory {
    
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
   
   @Override
   public Color getColor(String color) {
      if(color == null){
         return null;
      }        
      if(color.equalsIgnoreCase("RED")){
         return new Red();
      } else if(color.equalsIgnoreCase("GREEN")){
         return new Green();
      } else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      }
      return null;
   }
}

工厂生成器

public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
      } else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
      return null;
   }
}

该类的作用是根据传入的条件创建具体工厂。

以上即是抽象工厂模式的大致结构,要想获取具体对象,先通过FactoryProducer类中的getFactory()获取AbstractFactory,再通过传入相应条件来获取实体类对象。


扩展:

1.在抽象工厂模式中,假设我们需要增加一个工厂(事实上是增加了产品和工厂),那该怎么做呢?

在如上代码中,假设我们要增加一个材质工厂MaterialFactory,第一步需要生成Material接口,并创建其实现类,即具体产品(Glass,Iron,Wood),第二步,在抽象工厂类中创建新的抽象方法getMaterial(),第三步,创建工厂类MaterialFactory,重写其抽象方法getMaterial(),第四步,在工厂生成器中增加判断条件。

当然若我们的结构是这样的话:即工厂类中的产品来自不同类(看UML图)
在这里插入图片描述
上图中,产品接口的父类是一个抽象类。
在这里插入图片描述
增加一个工厂(产品族)只需:
在这里插入图片描述
而增加一个新的产品(新的产品种类)需要:
在这里插入图片描述
这里修改了抽象类及其子类,违背了开闭原则。

2.它体现了设计模式中什么原则?

符合开闭原则单一职责原则

3.它的缺点是什么?

当增加一个新的产品种类时,此时就必须去修改抽象工厂,这样就涉及到抽象工厂类的以及所有子类的改变,这样也就违背了“开发——封闭”原则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Uranus^

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值