在现实生活中社会分工越来越细,越来越专业化。各种产品有专门的工厂生产,彻底告别了自给自足的小农经济时代,这大大缩短了产品的生产周期,提高了生产效率。
同样,在软件开发中能否做到软件对象的生产和使用相分离呢?
能否在满足“开闭原则”的前提下,客户随意增删或改变对软件相关对象的使用呢?
定义
工厂(factory)模式属于创建型模式,定义了一个创建对象的工厂接口,将产品对象的实际创建工作推迟到具体的工厂类中。
我们把被创建的对象成为产品
,把创建产品的对象成为工厂
如果要创建的产品不多,只要一个工厂类就可以完成,这种模式叫简单工厂模式
,它不属于23种设计模式,缺点是增加新产品时会违背开闭原则
工厂分类
以家电为例,区分说明工厂模式的几个概念
- 在还有工厂时代:如果客户需要一台冰箱,一般的做法是自己去造一台冰箱,然后拿来用,也就是我们常用的通过new操作符自己创建对象实例。
- 简单工厂模式:用户不用自己造冰箱,会有一个工厂来帮他造海尔冰箱,想要什么型号的海尔冰箱,这个工厂就可以建造。这个工厂就是创建海尔系列的冰箱。
- 工厂方法模式:为了满足客户的需求,海尔集团的产品越来越多,有冰箱,空调,热水器等。一个工厂无法创建所有的产品,于是单独分出很多具体的工厂,每个工厂创建一种产品,即具体工厂只能创建一个具体的同类的产品。
- 抽象工厂模式:随着家电的发展,出现了格力,美的等等。我们对产品再次进行分类,比如海尔的冰箱,格力的冰箱,美的的冰箱等同归于一个工厂,都可以生产,而空调则在另外一个工厂生产。每个工厂都能生产出一组的产品来。
综上所述:工厂模式总体分为三类
- 简单工厂模式(simple factory)
- 工厂方法模式(factory method)
- 抽象工厂模式(abstract factory)
三种模式从上到下逐步抽象,同时也可将工厂模式分为两类:工厂方法模式和抽象工厂模式。将简单工厂模式看做为工厂方法的一种特例。
简单工厂模式
简单工厂描述
简单工厂模式又称静态工厂模式.它存在的目的就是定义一个用于创建对象的接口。
它的组成:
- 工厂类角色:本模式的核心,含有一定的逻辑或者判断。由一个具体类实现。
- 抽象产品角色:是具体产品继承的父类或者实现的接口。由抽象类或者接口来实现。
- 具体产品角色: 工厂类所创建的对象就是此角色的实例,由具体类实现。
简单工厂实现
代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
public interface Appliance {
void display();
}
public class Refrigerator1 implements Appliance {
@Override public void display() { System.out.println("型号1的冰箱"); } }
public class Refrigerator2 implements Appliance {
@Override public void display() { System.out.println("型号2的冰箱"); } }
public class RefrigeratorFactory { public static Appliance build(String type) { if(type.equals("1")) { return new Refrigerator1(); } else { return new Refrigerator2(); } } }
public static void main(String[] args) { Refrigerator refrigerator = RefrigeratorFactory.build("1"); refrigerator.display(); }
|
使用了简单工厂模式后,我们不需要再关注产品创建的过程,仅仅负责获取产品即可。
参考上面的工厂方法简介,假如这个时候,我们需要开始生产电视,空调了,这个工厂该怎么办?再次打造出一个生产线,甚至重新定义产品,带来的代价太大了,因此我们可以考虑工厂模式了。
工厂模式
工厂模式结构
工厂模式去掉了简单工厂模式中的静态方法,使得它可以被子类继承。这样在简单工厂模式中集中在工厂方法的压力就可以由工厂方法模式里的不同工厂子类来分担。
工厂模式的结构如下:
- 抽象工厂(abstract factory)角色:这是工厂模式的核心,提供创建产品的接口,调用者通过它访问具体工厂的工厂方法来创建产品。
- 具体工厂(concrete factory)角色: 主要实现抽象工厂的抽象方法。完成具体产品的创建
- 抽象产品(product):定义了产品的规范,描述了产品的主要特征和功能
- 具体产品(concrete product):实现了抽象产品角色所定义的接口,由具体工厂创建,同具体工厂之间一一对应。
其结构图如下:
工厂模式实现
代码实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
public interface Appliance {
void display();
}
public class Television implements Appliance {
@Override public void display() { System.out.println("电视"); } }
public class Refrigerator implements Appliance {
@Override public void display() { System.out.println("冰箱"); } }
public interface ApplianceFactory {
Appliance build(); }
public class RefrigeratorFactory implements ApplianceFactory {
@Override public Appliance build() { return new Refrigerator(); } }
public class TelevisionFactory implements ApplianceFactory {
@Override public Appliance build() { return new Television(); } }
public static void main(String[] args) { ApplianceFactory refrigeratorFactory = new RefrigeratorFactory(); Appliance refrigerator = refrigeratorFactory.build();
ApplianceFactory televisionFactory = new TelevisionFactory(); Appliance television = televisionFactory.build();
refrigerator.display(); television.display(); }
|
抽象工厂方法
抽象工厂模式描述
随着家电市场的扩大,出现了很多品牌的家电,比如海尔,格力等等,工厂此时也接到了更多的订单,比如生产海尔的电视,冰箱,格力的电视,冰箱等,我们此时就需要对业务线再次进行升级,于是用到了抽象工厂方法。
首先认识下什么是产品族:位于不同产品等级结构中,功能相关联的产品组成的家族。比如海尔的电视和海尔的冰箱都属于海尔品牌的家电,格力的电视和格力冰箱都属于格力品牌的家电。
抽象工厂模式和工厂方法的区别在于需要创建对象的复杂程度上。抽象工厂模式是三个里面最为抽象的,最具一般性的,抽象工厂模式的定义为:是一种为访问类提供一个创建一组相关或者相互依赖对象的接口,且访问类无须指定所要产品的具体类就能得到同族的不同等级的产品的模式结构。
要使用抽象工厂模式,一般需要满足以下条件:
- 系统中有多个产品族,每个具体工厂创建同一族但属于不同等级结构的产品。
- 系统一次只可能消费其中某一族产品,即同族的产品一起使用。
抽象工厂模式结构
抽象工厂模式的主要角色如下:
- 抽象工厂(abstract factory):提供了创建产品的接口,包含了多个创建产品的方法,可以创建多个不同等级的产品。
- 具体工厂(concrete factory):主要实现抽象工厂中的多个抽象方法,完成具体产品的创建
- 抽象产品(product):定义了产品的规范,描述了产品的主要特征和功能,抽象工厂模式有多个抽象产品.
- 具体产品(concrete product):实现了抽象产品角色定义的接口,由具体工厂来创建,同具体工厂之间是多对一的关系。
其结构图如下:
抽象工厂模式实现
具体实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
public interface Television {
void display(); }
public interface Refrigerator {
void display(); }
public interface ApplianceFactory {
Television buildTelevision();
Refrigerator buildRefrigerator(); }
public class GeliRefrigerator implements Refrigerator {
@Override public void display() { System.out.println("格力冰箱"); } }
public class GeliTelevision implements Television {
@Override public void display() { System.out.println("格力电视"); } }
public class HaierRefrigerator implements Refrigerator {
@Override public void display() { System.out.println("海尔冰箱"); } }
public class HaierTelevision implements Television {
@Override public void display() { System.out.println("海尔电视"); } }
public class HaierFactory implements ApplianceFactory {
@Override public Television buildTelevision() { return new HaierTelevision(); }
@Override public Refrigerator buildRefrigerator() { return new HaierRefrigerator(); } }
public class GeliFactory implements ApplianceFactory {
@Override public Television buildTelevision() { return new GeliTelevision(); }
@Override public Refrigerator buildRefrigerator() { return new GeliRefrigerator(); } }
public static void main(String[] args) { ApplianceFactory haierFactory = new HaierFactory(); ApplianceFactory geliFactory = new GeliFactory();
Television haierTel = haierFactory.buildTelevision(); Refrigerator haierRe = haierFactory.buildRefrigerator();
Television geliTel = geliFactory.buildTelevision(); Refrigerator geliRe = geliFactory.buildRefrigerator();
haierTel.display(); haierRe.display(); geliTel.display(); geliRe.display(); }
|