模式定义
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
模式结构
模式结构
代码实现
//早餐工厂
public interface BreakfastFactory {
Food makeFood();
Drink makeDrink();
}
//饮料工厂
public interface Drink {
void drink();
}
//实现类
public class EastDrink implements Drink {
public void drink() {
System.out.println("喝豆浆");
}
}
public class WestDrink implements Drink {
public void drink() {
System.out.println("喝牛奶");
}
}
//主食工厂
public interface Food {
void eat();
}
//实现类
public class EastFood implements Food {
public void eat() {
System.out.println("吃油条");
}
}
public class WestFood implements Food {
public void eat() {
System.out.println("吃面包");
}
}
//早餐工厂实现类(中式早餐)
public class EastBreakfast implements BreakfastFactory {
public Food makeFood() {
return new EastFood();
}
public Drink makeDrink() {
return new EastDrink();
}
}
//西式早餐
public class WestBreakfast implements BreakfastFactory {
public Food makeFood() {
return new WestFood();
}
public Drink makeDrink() {
return new WestDrink();
}
}
public class Client {
public static void main(String[] args) {
System.out.println("**********第一天吃西餐***********");
BreakfastFactory breakfast = new WestBreakfast();
breakfast.makeDrink().drink();
breakfast.makeFood().eat();
System.out.println("**********第一天吃中餐***********");
breakfast = new EastBreakfast();
breakfast.makeDrink().drink();
breakfast.makeFood().eat();
}
}
运行结果:
**********第一天吃西餐***********
喝牛奶
吃面包
**********第一天吃中餐***********
喝豆浆
吃油条
模式的优缺点
优点
分离接口和实现
客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦。使得切换产品簇变的容易
比如上面的例子:中餐是喝豆浆、吃油条;西餐是喝牛奶、吃面包。你也可以将中餐改为喝豆浆、吃面包。
缺点
不太容易扩展新的产品
容易造成类层次复杂
举个例子来说:比如DAO,现在DAO只有一个选择的层次,也就是选择是使用关系型数据库来实现,还是使用XML实现。现在考虑这样一种情况,如果关系型数据库实现里面又分成几种,比如,基于Oracle的实现、基于SqlServer的实现、基于MySQL的实现等。
那么客户端怎么选择呢?不会把所有的实现情况全都做到一个层次上吧,这个时候客户端就需要一层一层地选择,也就是整个抽象工厂的实现也需要分出层次来,每一层负责一种选择,也就是一层屏蔽一种变化,这样很容易造成复杂的类层次结构。
思考
模式本质:选择产品簇的实现。
开发中的应用场景
如果希望一个系统独立于它的产品的创建、组合和表示的时候。换句话说,希望一个系统只是知道产品的接口,而不关心实现的时候。
可以动态的切换产品簇的时候。
如果要强调一系列相关产品的接口,以便联合使用它们的时候。