一、含义
工厂模式包含两个方式:一个是抽象工厂模式,一个是工厂方法模式。
抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。
工厂方法模式:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类中。
二、要点
1.工厂模式都是用来封装对象的创建。
2.工厂方法使用继承:把对象的创建委托给子类,子类实现工厂方法来创建对象。
3.抽象工厂使用对象组合:对象的创建被实现在工厂接口所暴露出来的方法中。
4.工厂模式的作用是减少程序和具体类之间的依赖促进松耦合。
三、实战分析工厂模式。
需求:对于一个厌倦了编码的程序猿来说,回家开个餐厅是个不错的选择,卖汉堡就是一个不错的选择。
首先就是开一个汉堡店,由于汉堡的种类繁多,在汉堡店的实例中,我就需要更具类型来实例很多不同种类的汉堡,如下所示:
Hamburg orderHamburg(String type) {
Hamburg hamburg;
//实例具体的汉堡工作,随着汉堡的不同,这里的代码就需要修改
if (type.equals("beef")) {
hamburg = new BeefHamburg();
} else if (type.equals("mutton")) {
hamburg = new MuttonHamburg();
} else if (type.equals("bigMAC")) {
hamburg = new BigMACHamburg();
}
//这些步骤是通用的,不需要修改
hamburg.prepare();
hamburg.bake();
hamburg.box();
return hamburg
}
所以直接在汉堡店中实例化汉堡,程序的耦合多太高,我们可以把创建汉堡的过程,给他抽离出来,单独封装成一个用来创建汉堡的实例类:
public class SimpleHamburgFactory {
public Hamburg createHamburg(String type) {
Hamburg hamburg;
if (type.equals("beef")) {
hamburg = new BeefHamburg();
} else if (type.equals("mutton")) {
hamburg = new MuttonHamburg();
} else if (type.equals("bigMAC")) {
hamburg = new BigMACHamburg();
}
return hamburg;
}
}
这个时候汉堡店的设计就可如下:
public class HamburgStore {
//传递一个用来实例化汉堡实体的工厂
SimpleHamburgFactory simpleHamburgFactory;
public HamburgStore(SimpleHamburgFactory simpleHamburgFactory) {
this.simpleHamburgFactory = simpleHamburgFactory;
}
Hamburg orderHamburg(String type) {
Hamburg hamburg;
hamburg = simpleHamburgFactory.createHamburg(type);
hamburg.prepare();
hamburg.bake();
hamburg.box();
return hamburg
}
}
在你精心经营下,你的汉堡店越做越大,有很多加盟商想要加盟,加盟商根据所在地点的不同,可能生产的汉堡有所不同,我们的总店就相当于一个超类,别的加盟商就是需要实现这个超类,然后去自定义生产汉堡。总店的设计如下:
public abstract class HamburgStore {
public Hamburg orderHamburg(String type) {
hamburg = createHamburg(type);
hamburg.prepare();
hamburg.bake();
hamburg.box();
return hamburg;
}
//定义一个抽象方法,让继承的子类去实现用什么工厂创建
abstract Hamburg createHamburg(String type);
}
所以工厂模式的类型可以如下去理解:
为什么我们的汉堡可以买的这么好呢?就是因为我们自己独特的秘制配料,比如说面粉,酱料等,随着加盟商的增多,我们的配料也需要根据地方的不通,就行生产,这是使用我们就需要一个专门制作配料的工厂。
public interface HamburgIngredientFactory {
//每个原料都有一个对应的方法创建该原料
Dough createDough();
Sauce createSauce();
Cheese createCheese();
Pepperoni createPepperoni();
Clams createClam()s;
}
然后需要做的事就是为每个区域建造一个工厂,继承至HamburgIngredientFactory,还需要提供一组原料类,来使用,最后将这些原料整合到HamburgStore中去。
public class SiChuangHamburgIngredientFactory implements HamburgIngredientFactory {
@Override
public Dough createDough() {
return new SiChuanDough();
}
@Override
public Sauce createSauce() {
return new SiChuanSauce();
}
@Override
public Cheese createCheese() {
return new SiChuanCheese();
}
@Override
public Pepperoni createPepperoni() {
return new SiChuanPepperoni();
}
@Override
public Clams createClam() {
return new SiChuanClams();
}
}
重新设计汉堡类
public abstract class Hamburg {
String name;
//这些都是汉堡需要用到的原料
Dough dough;
Sauce sauce;
Pepperoni pepperoni;
Clams clams;
//这个准备工作就是收集汉堡所需的原料,这些原料需要用工厂来实现
abstract void prepare();
void bake() {
System.out.println("Bake 20 minutes");
}
void box() {
System.out.println("hamburg put box");
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
设计一个具体的类 :
public class CheeseHamburg extends Hamburg {
//需要一个原料工厂来提供原料
HamburgIngredientFactory hamburgIngredientFactory;
public CheeseHamburg(HamburgIngredientFactory hamburgIngredientFactory) {
this.hamburgIngredientFactory = hamburgIngredientFactory;
}
@Override
void prepare() {
dough = hamburgIngredientFactory.createDough();
sauce = hamburgIngredientFactory.createSauce();
clams = hamburgIngredientFactory.createClam();
}
}
从上诉代码中可以看出,所有抽象工厂的类图,可以如下图所示: