一、抽象工厂模式的定义
provides an interface for creating families of related or dependent objects without specifying their concrete classes.
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定它们的具体类
二、抽象工厂模式的应用
1、抽象工厂模式的优点
封装性。每个产品的实现类不是高层模块要关心的,它要关心的是接口,是抽象。工厂类负责类的创建需要的对象
产品族的约束是非公开的。高层模块根本不需要关心这个,在工厂类中实现即可。
2、抽象工厂模式的缺点
产品族的扩展非常困难,如例子中如果要增加一个产品C,则需要修改抽象工厂类,增加一个产品C的接口,然后实现类也需要修改,抽象类和接口是一个契约,改变契约,则与契约相关的代码都要修改,这样是严重违反开闭原则
抽象工厂类只是扩展产品族困难,而不是产品等级,在该模式下的产品等级非常容易扩展,比如要增加一个等级3的A和B产品,只要增加一个工厂类负责新增加出来的产品生产任务即可,也就是说 横向扩展容易,纵向扩展困难。
3、抽象工厂模式的使用场景
一个系统要独立于它的产品的创建、组合和表示时,一个系统要由多个产品系列中的一个来配置时,需要强调一系列相关的产品对象的设计以便进行联合使用时,提供一个产品类库,而只想显示它们的接口而不是实现时,抽象工厂模式是工厂方法模式的横向扩展。
三、抽象工厂方法模式的写法
//抽象产品类
public abstract class AbstractProductA {
//每个产品的共有方法
public void shareMethod () {
}
//每个产品相同方法,不同实现
public abstract void doSomething ();
}
//抽象产品类
public abstract class AbstractProductB {
//每个产品的共有方法
public void shareMethod () {
}
//每个产品相同方法,不同实现
public abstract void doSomething ();
}
//具体产品类A1
public class ProductA1 extends AbstractProductA {
public void doSomething () {
System.out.print("产品类A1的实现");
}
}
//具体产品类A2
public class ProductA2 extends AbstractProductA {
public void doSomething (){
System.out.print("产品类A2的实现");
}
}
//具体产品类B1
public class ProductB1 extends AbstractProductB {
public void doSomething (){
System.out.print("产品类B1的实现");
}
}
//具体产品类B2
public class ProductB2 extends AbstractProductB {
public void doSomething (){
System.out.print("产品类B2的实现");
}
}
//抽象工厂类
public abstract class AbstractCreator {
//创建A产品家族
public abstract AbstractProductA createProductA();
//创建B产品家族
public abstract AbstractProductB createProductB();
}
//具体工厂类产品等级1的实现类
public class Creator1 extends AbstractCreator {
//只生产产品等级为1的A产品
public AbstractProductA createProductA () {
return new ProductA1();
}
//只生产产品等级为1的B产品
public AbstractProductB createProductB () {
return new ProductB1();
}
}
//具体工厂类产品等级2的实现类
public class Creator2 extends AbstractCreator {
//只生产产品等级为2的A产品
public AbstractProductA createProductA () {
return new ProductA2();
}
//只生产产品等级为1的B产品
public AbstractProductB createProductB () {
return new ProductB2();
}
}
四、抽象工厂模式在源码中的应用
抽象工厂模式是在源码中运用的比较少的
Activity中的onCreate和Service中的onBind都可以看做一个工厂方法,从framework角度来看Activity和service都可以作是一个具体的工厂
IPolicy是产生窗口屏幕相关对象的抽象接口,在Android手机源码中,com.android.internal.policy.impl.Policy是它的唯一一个实现,按照源码中的注释所说的,是Policy是IPolicy的一个简单实现,用来生成对象集合。Policy创建一系列的Phone的窗口相关对象:PhoneWindow,PhoneLayoutInflater,PhoneWindowManager,PhoneFallbackEventHandler。IPolicy算是一个典型的抽象工厂,只不过在源码中只有一个具体的工厂实现。
另外Policy的实现还有一点特殊的地方,它使用static域将他需要创建的对象都预先load出来,也就是说当虚拟机加载Policy类的时候,就会加载它创建的对象的class。
不同源码版本可能不一致
PolicyManager
public static Window makeNewWindow(Context context) {
return sPolicy.makeNewWindow(context);
}
Window与PhoneWindow
final void attach(Context context, ActivityThread aThread,
Instrumentation instr, IBinder token, int ident,
Application application, Intent intent, ActivityInfo info,
CharSequence title, Activity parent, String id,
NonConfigurationInstances lastNonConfigurationInstances,
Configuration config, IVoiceInteractor voiceInteractor) {
attachBaseContext(context);
mFragments.attachActivity(this, mContainer, null);
mWindow = PolicyManager.makeNewWindow(this);
mWindow.setCallback(this);
mWindow.setOnWindowDismissedCallback(this);
mWindow.getLayoutInflater().setPrivateFactory(this);
...
attach方法是将Context,application等赋值给Activity,在Activiy启动的过程会调用。我们弹出的对话框(Dialog),里面也是有一个Window的。另外与Activity对应的还有启动窗口(Starting Window)。一个Window还可以有子Window。