模式意图
提供对象的使用接口,隐藏对象的创建过程。
模式结构
AbstractFactory 提供创建对象的接口。ConcreteFactory 提供真正创建对象的实现类,用于组合并创建不同的对象,实现一个产品族。AbstractProduct 提供对象的使用接口。ConcreteProduct 提供真正的适用对象,隐藏该对象的创建过程,是工厂创建的对象。Client 使用者,通过抽象工厂接口,使用不同的具体工厂方法创建对象组合,从而直接使用对象,无需关注对象的创建过程。
适合场景
1 系统独立于它的产品创建、组合和表示。即无需关心内部对象时如何创建的,怎么创建的,什么含义。
2 系统需要多个产品组合中的一个配置。由于对象很多,能够组合出的组合非常多,而系统只是使用某一个组合。
3 强调的对象的组合结果,而不是他们具体的接口和实现。
代码结构
AbstractFactory.java
interface AbstractFactory { public AbstractProductA CreateProductA(); public AbstractProductB CreateProductB();}
ConcreteFactory.java
class ConcreteFactory1 implements AbstractFactory{ @Override public AbstractProductA CreateProductA() { return new ConcreteProductA1(); } @Override public AbstractProductB CreateProductB() { return new ConcreteProductB1(); }}
AbstractProduct.java
interface AbstractProductA { public void use();}interface AbstractProductB { public void use();}
ConcreteProduct.java
class ConcreteProductA1 implements AbstractProductA{ @Override public void use() { // TODO Auto-generated method stub System.out.println("use A1 product!"); }}class ConcreteProductB1 implements AbstractProductB{ @Override public void use() { // TODO Auto-generated method stub System.out.println("use B1 product!"); }}
使用方式
public static void main(String[] args){ AbstractProductA pa; AbstractProductB pb; AbstractFactory fa1 = new ConcreteFactory1(); pa = fa1.CreateProductA(); pb = fa1.CreateProductB(); pa.use(); pb.use(); AbstractFactory fa2 = new ConcreteFactory2(); pa = fa2.CreateProductA(); pb = fa2.CreateProductB(); pa.use(); pb.use(); }
全部代码
1 package com.designer; 2 interface AbstractFactory { 3 public AbstractProductA CreateProductA(); 4 public AbstractProductB CreateProductB(); 5 } 6 interface AbstractProductA { 7 public void use(); 8 } 9 interface AbstractProductB {10 public void use();11 }12 class ConcreteFactory1 implements AbstractFactory{13 14 @Override15 public AbstractProductA CreateProductA() {16 return new ConcreteProductA1();17 }18 19 @Override20 public AbstractProductB CreateProductB() {21 return new ConcreteProductB1();22 }23 24 }25 class ConcreteFactory2 implements AbstractFactory{26 27 @Override28 public AbstractProductA CreateProductA() {29 return new ConcreteProductA2();30 }31 32 @Override33 public AbstractProductB CreateProductB() {34 return new ConcreteProductB2();35 }36 37 }38 class ConcreteProductA1 implements AbstractProductA{39 40 @Override41 public void use() {42 // TODO Auto-generated method stub43 System.out.println("use A1 product!");44 }45 46 }47 class ConcreteProductA2 implements AbstractProductA{48 49 @Override50 public void use() {51 // TODO Auto-generated method stub52 System.out.println("use A2 product!");53 }54 55 }56 class ConcreteProductB1 implements AbstractProductB{57 58 @Override59 public void use() {60 // TODO Auto-generated method stub61 System.out.println("use B1 product!");62 }63 64 }65 class ConcreteProductB2 implements AbstractProductB{66 67 @Override68 public void use() {69 // TODO Auto-generated method stub70 System.out.println("use B2 product!");71 }72 73 }74 public class Client {75 public static void main(String[] args){76 AbstractProductA pa;77 AbstractProductB pb;78 79 AbstractFactory fa1 = new ConcreteFactory1();80 pa = fa1.CreateProductA();81 pb = fa1.CreateProductB();82 pa.use();83 pb.use();84 85 AbstractFactory fa2 = new ConcreteFactory2();86 pa = fa2.CreateProductA();87 pb = fa2.CreateProductB();88 pa.use();89 pb.use();90 91 }92 }
生活中的设计模式
在生活中,我们经常会碰到使用一系列东西的时候。比如,我们愿意吃炸鸡配啤酒,喜欢吃爆米花配可乐。我们不关心炸鸡怎么炸的,啤酒怎么酿的,爆米花怎么爆的,而只关心我们吃什么,喝什么,这就是典型的抽象工厂。
例如,大部分程序猿们都有吃早餐的习惯,当然很多人喜欢睡懒觉也来不及吃,但是为了身体健康,还是要按时吃饭才行!扯远了...
有人喜欢吃中式的,有人喜欢吃西式的。那么去食堂我们不会去问,包子怎么做的,面包怎么烤的,仅仅是付费吃饭而已。而中式一般是豆浆油条,西式面包牛奶。这种搭配已经形成了一种习惯,也就是默认的产品组合。
因此,我们在买单时,只要指定早餐的样式,就可以了。下面就是我们吃早餐,使用早餐工厂的流程...
interface BreakfastFactory{ public StapleFood MakeStapleFood(); public Drinks MakeDrinks();}interface StapleFood{ public void eating();}interface Drinks{ public void drinking();}class BreakfastCStyle implements BreakfastFactory{ @Override public StapleFood MakeStapleFood() { return new DeepFriedDoughSticks(); } @Override public Drinks MakeDrinks() { return new SoybeanMilk(); } }class BreakfastWStyle implements BreakfastFactory { @Override public StapleFood MakeStapleFood() { return new Bread(); } @Override public Drinks MakeDrinks() { return new Milk(); }}class DeepFriedDoughSticks implements StapleFood{ @Override public void eating() { System.out.println("我在吃油条!..."); }}class SoybeanMilk implements Drinks{ @Override public void drinking() { System.out.println("我在喝豆浆!..."); }}class Bread implements StapleFood{ @Override public void eating() { System.out.println("我在吃面包!..."); }}class Milk implements Drinks{ @Override public void drinking() { System.out.println("我在喝牛奶!..."); }}public class Breakfast{ public static void main(String[] args){ StapleFood sf; Drinks dk; System.out.println("——————————————————第一天——————————————————————————"); System.out.println("我要吃中式早餐"); BreakfastFactory bf1 = new BreakfastCStyle(); sf = bf1.MakeStapleFood(); dk = bf1.MakeDrinks(); sf.eating(); dk.drinking(); System.out.println("——————————————————第二天——————————————————————————"); System.out.println("我要吃西式早餐"); BreakfastFactory bf2 = new BreakfastWStyle(); sf = bf2.MakeStapleFood(); dk = bf2.MakeDrinks(); sf.eating(); dk.drinking(); }}
可以看到,非常方便的就迟到了中式和西式的早餐,而省掉了大量炸油条,烤面包的时间。
——————————————————第一天——————————————————————————我要吃中式早餐我在吃油条!...我在喝豆浆!...——————————————————第二天——————————————————————————我要吃西式早餐我在吃面包!...我在喝牛奶!...
这就是一个简单的抽象工厂的使用。