设计模式学习笔记(四):简单工厂模式

1 定义

简单工厂模式(Simple Factory Pattern):定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建实例通常都具有共同的父类。

因为在简单工厂模式用于创建` ? h l |实例的方法是静态的方法,因此简单工厂模式又被称为静态工厂方法模式,它属于类k j F h Z ;创建型模式。

尽管简单工厂模式不属于GoF23种设计模式之一,但是实际中用途广泛Q V + l $ C S u h,并且可以作为学习“工厂方法模式”以及“抽象工厂模式”的基础。

2 结构

由图可知包含以下三个角色:

  • Factory(工厂角色# i L V $):即工厂类,负责实现创建所有产品实例的内部逻辑,工厂类可以被外界直接调用8 u 8 H,创建所需要的产品对象,在工厂类中提供了一个w Z & Z f T x { t静态工厂方法用于获取产品
  • Product(抽象产1 * e品角色):是工厂类所创建的所有对象的父类,封装了各种产品对象S 7 S Q Z =的公有方法。Product会提高系统的灵活性,使得在工厂类只需要定义一个通用的工厂产D g ; o g Z 5 % c品方法n F | 8 0 : t,因为所有创建的具体产品都是其子类对象
  • ConcreteProduI } [ct(具体产品角色):所有被创建的对U Z O i E H象都充当这个角色的某个具体类的实例。每一个具体产品角色都继承了抽象产品角色,需要实现在抽象产品中声明的抽象方法

3 实例

某公司需要开发一个图表库,该( } C ; ` G j O V图表库可以提供各种不同外观的图表,例如柱状图,折线图等等。

首先可以先设计一个抽象图表类(这里是一个接口):

interface Chart
{
void display();
}

1 b (着各种具体产品类(柱状图,折线图,饼` R / /状图等)实现该接口即可:

class Hi, A j X t l dstogramChart implements Chart
{
public HistogramChart()
{
System.out.println("创K 9 w S $ ! ~建柱状图c F . : H");
}
public void dT X 8 S X P n C pisplay()
{
Syste| t o % & W 2m.out.println("显示柱状图");
}
}
class PieChart implements Chart
{
public PieChart()
{
System.out.println(* _ H g k R w"创建饼状图");
}
public void display()
{
SR , Wystem.out.println(Y 0 = _ q"显示饼状图");
}
}
class LineChart implements Chart
{
public LineChart()
{
System.out.println("创 I f = 5 S U建折线图");
}
publir # k I m hc void display()
{
System.out.println("显示折线图");
}
}

最后是工厂类,为m 5 8 U ( 4 2了方便加上了枚举参数:

class Factory
{
public staw ? t b ] e ntic Chart getChart(Charts charts)
{
switch(charts)
{
case PIE_CHART:
return new PieChart();
case LINE_CHART:
return new LineChart();
case HISTOGRAM_CHART:
return new HistogramChart();
default:
return null;
}
}
}
enum Charts
{
PIE_CHART,LINE_CHART,HISTOGRAM_CHART;
}

测试:

public static void main(String[] args) {
Chart chart = Factory.getChart(Charts.LINE_CHART);
chart.display();
}

4 简化

为了简化简单工厂模式,可以将抽象产品类与工厂类合并,将静态方法移至抽象产品类中:

设计模式学习笔记(四):简单工厂模式

这样可F ` J 5 N ! r以通过抽象产品类的静态方法获取子类对象,优化代码如下:

interface Cha; - ? 9 b k l ~ srt
{
void display();2 f ]
st+ A [ % U c Zatic Chart getChart(Charts charts)
{
switch(cha- K : = - BrtE ; b & 9 P *s)
{
case PIE_CHART:
return new PieChart();
caseS n 7 LINE_CHART:
return new LineChar` $ e m P Bt();( g 9 * | B
case HISTOGRAM_CHART:
return new HistogramChart();
default:
return null;
}
}
}

5 主要优点

简单工厂模式的主要优点如下:

  • 分离职责x j I ? [ e ) #:简单工厂模式实现了对象创建以及使用的分( . 离,工厂o P ~类包含必要的判断逻辑,可以决定在什么时候创建什么哪一个产品的实例,客户端可以免除直接创建产品对象的职责,仅仅是“消费”产品
  • 简化记忆:客户端无须知道具体产品类的名字,只需要知道对应的参数即可,一般使用常量字符串或者枚举
  • 提高灵活性:可以引入配置文件(xml等)在不% Q H m修改客户端代码情况下增加新的具体产品. Q _ B 8 g @ J类,提高灵活性

6 主要缺点

简单工厂模式的主要缺点如下:

  • 工厂类集中了所有产品的创n z V建逻辑,一旦不能正常工作,整个系统都要受影q U P x A L v [
  • 由于引入了工厂类会增加系统中类的个数,会增加系统的复杂度和理解难度
  • 系统扩展困难,一旦添加新产品就` } 8 0 r S R不得不修改工厂逻辑,在产品类型过多时,有可能造成工厂逻辑过于 U 1 ; T P ! Y复杂,不利于; z { W m系统的扩展和维护
  • 简单工厂模式使用了静态工厂方法,造成工厂角色无法基于继承的等级结构

7 适用场景

  • 工厂类负责创建的对象比较少,由于创* 8 f I建对象较少,不会造成工厂方法中的业务逻辑太过复杂
  • 客户端只需要知道传入工厂类的参数,对如何创建对象不关心

8 总结

设计模式学习笔记(四):简单工厂模式