java设计模式之抽象工厂模式

Posted J_Newbie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java设计模式之抽象工厂模式相关的知识,希望对你有一定的参考价值。

定义:

抽象工厂模式指提供一个创建一系列相关或者相互依赖对象的接口,无须指定他们具体的类,意思是客户端不必指定产品的具体类型,创建多个产品族中的产品对象。

抽象工厂模式中,客户端不依赖产品类如何被创建,实现等细节,强调一系列相关的产品对象一起创建对象,需要大量重复的代码

需要提供一个产品的类库,所有的产品以同样的接口出现,从而使客户端不依赖具体的实现

产品等级结构和产品族

上图中有矩形,圆形和菱形3中图形,相同颜色,相同深浅的代表同一个产品族,相同形状的代表同一个产品等级。

应用场景:

抽象工厂模式适用于需要生成产品族的情景,抽象产品类内部提供了多个其他抽象产品,抽象工厂类定义了产品的创建接口,通过具体的工厂子类,就可以生产相应的产品族对象,供用户端使用

抽象工厂的UML类图:

 

 

右上图可知,抽象工厂模式主要包含4个角色

  1. 抽象工厂:声明创建抽象产品对象的一个操作接口

  2. 具体工厂:实现创建具体产品对象的操作

  3. 抽象产品:为一类产品对象声明一个接口

  4. 具体产品:定义一个将被相应的具体工厂创建的产品对象,实现AbstractProduct接口

抽象工厂模式的通用写法:

public class Client
  public static void main(String[] args)
    IFactory factory = new ConcreateFactoryA();
    factory.makeProductA();
    factory.makeProductB();
    
    factory = new ConcreateFactoryB();
    factory.makeProductA();
    factory.makeProductB();
  

//抽象工厂
public interface IFactory
  IProductA makeProductA();
  
  IProductB makeProductB();

//产品A抽象
public interface IProductA
  void doA();

//产品B抽象
public interface IProductB
  void doB();

//产品族A的具体产品A
public class ConcreateProductAWithFamilyA implements IProductA
  public void doA()
    System.out.println("The ProductA be part of FamilyA")
  

//产品族A的具体产品B
public class ConcreateProductWBithFamilyA implements IProductB
  public void doB()
    System.out.println("The ProductB be part of FamilyA")
  

//产品族B的具体产品A
public class ConcreateProductAWithFamilyB implements IProductA
  public void doA()
    System.out.println("The ProductA be part of FamilyB")
  

//产品族B的具体产品B
public class ConcreateProductWBithFamilyB implements IProductB
  public void doB()
    System.out.println("The ProductB be part of FamilyB")
  

//具体工厂类A
public class ConcreateFactoryA implements IFactory
  public IProductA makeProductA()
    return new ConcreateProductAWithFamilyA();
  
  
  public IProductB makeProductB()
    return new ConcreateProductBWithFamilyA();
  


//具体工厂类B
public class ConcreateFactoryB implements IFactory
  public IProductA makeProductA()
    return new ConcreateProductAWithFamilyB();
  
  
  public IProductB makeProductB()
    return new ConcreateProductBWithFamilyB();
  

实例:

我们来看一个具体的业务场景,并且用代码来实现。还是以课程为例,假设每个课程要提供课程的录播视频还有课堂笔记,相当于现在的业务包括一个课程要有课程信息,录播视频,课堂笔记,甚至提供源码,首先在产品等级中增加两个产品,录播视频和课堂笔记

IVideo接口的代码如下:

public interface IVideo
  void record();

INote接口代码如下

public interface INote
  void note();

然后创建一个抽象工厂CourseFactory类:

public abstract class CourseFactory
  public void init()
    System.out.println("初始化基础数据");
  
  protected abstract INote createNote();
  protected abstract IVideo createVideo();

接下来创建Java产品族,Java视频JavaVideo类的代码如下:

public class JavaVideo implements IVideo
  public void record()
    System.out.println("录制Java视频");
  

扩展产品等级Java课堂笔记JavaNote类

public class JavaNote implements INote
  public void note()
    System.out.println("编写Java笔记");
  

创建java产品族的具体工厂JavaCourseFactory

public class JavaCourseFactory extends CourseFactory
  public INote createNote()
    super.init();
    return new JavaNote();
  
  public IVideo createVideo()
    super.init();
    return new JavaVideo();
  

随后创建Python产品族,Python视频PythonVideo类的代码如下

public class PythonVideo implements IVideo
  public void record()
    System.out.println("录制python视频");
  

扩展产品等级Python课堂笔记PythonNote类

public class PythonNote implements INote
  public void note()
    System.out.println("编写Python笔记");
  

创建Python产品族的具体工厂PythonCourseFactory

public class PythonCourseFactory extends CourseFactory
  public INote createNote()
    super.init();
    return new PythonNote();
  
  public IVideo createVideo()
    super.init();
    return new PythonVideo();
  

最后来看客户端调用代码

public static void main(String[] args)
  JavaCourseFactory factory = new JavaCourseFactory();
  factory.createNote().note();
  factory.createVideo().record();

上面代码完整的描述了Java课程和Python课程两个产品族,抽象工厂模式非常清晰描述了这样一层的复杂关系。但是,不知道如果继续扩展产品,将Source也加入课程中,则代码从抽象工厂到具体的工厂要全部调整,这显然不符合开闭原则。

优点:

  1. 当需要产品族时,抽象工厂可以保证客户端始终只是用同一个产品的产品族

  2. 抽象工厂增强了程序的可扩展性,对于新产品族的增加,只需实现一个新的具体工厂即可,不需要对已有代码进行修改,符合开闭原则

缺点:

  1. 规定了所有可能被创建的产品集合,产品族中扩展新的产品困难,需要修改抽象工厂的接口

  2. 增加了系统的抽象性和理解难度

以上是关于java设计模式之抽象工厂模式的主要内容,如果未能解决你的问题,请参考以下文章

java设计模式之抽象工厂模式

JAVA设计模式——抽象工厂模式案例实现

设计模式之抽象工厂模式

java设计模式 -------- 创建模式 之 抽象工厂模式

23中设计模式之抽象工厂模式

设计模式-抽象工厂