意图
1,为创建一组相关或者互相依赖的对象提供一个接口,而无需指定它们对应的具体类
2,一个封装层次:有许多可能的“平台”, 但一次只可能消费其中一族 “产品”。
问题
如果应用程序是可移植的,它需要封装平台依赖性。这些“平台”可能包括:窗口系统,操作系统,数据库等太多的时候,这种封装没有事先设计的话,拥有大量的if else 选项 ,case语句,会产生对所有目前支持的平台像兔子一样乱窜的代码。
讨论
提供创建一个间接级别抽象相关或依赖对象的家族,而不直接指定它们具体的类。“工厂”对象为整个平台提供家族服务创造的责任。客户端从不直接创建平台对象,他们要求工厂代劳。
这种机制使得容易交换产品系列,因为特定的类厂对象只出现在应用程序中一次 即 它被实例化的时候。应用程序可以简单地通过实例化抽象工厂的不同的具体实例批量更换整个产品系列。
因为工厂对象所提供的服务是如此普遍,所以它通常是作为一个单例。
结构体
抽象工厂定义每个产品的工厂方法。每个工厂方法封装了新的操作,具体的,特定于平台的,产品类。然后 每个“平台”用一个工厂的派生类建模。
例子
抽象工厂的目的是提供一种用于创建相关对象的家族提供一个接口,而不指定具体类。这种模式在日本的汽车制造中使用的钣金冲压设备发现。冲压设备是一个抽象工厂创造车身零件。同样的机器被用来冲压右手门,左手车门,右前挡泥板,左前翼子板,发动机罩等汽车的不同模型。通过使用滚子以改变冲压模具,由机械产生的具体类可以在三分钟内被改变。
检查列表
1,决定是否“平台独立性”和服务的创建是痛苦的根源。
2,绘制出的“平台”与“产品”的矩阵。
3,定义一个工厂接口,由每一个产品的工厂方法组成。
4,定义派生类,封装了所有引用的每个平台的一个工厂新的操作。
5,客户应该替换所有的旧的引用到新的,并使用工厂方法来创建产品对象。
例子
抽象工厂类通常与工厂方法实现,但它们也可以使用原型实现。抽象工厂可以存储一组原型,从中克隆并返回的产品对象。
工厂方法:通过继承创建。
原型:通过委托创作。
虚拟构造函数:推迟对象的选择创建直到运行时。
public class FactoryFmProto
{
static class Expression
{
protected String str;
public Expression(String s)
{
str = s;
}
public Expression cloan()
{
return null;
}
public String toString()
{
return str;
}
}
static abstract class Factory
{
protected Expression prototype = null;
public Expression makePhrase()
{
return prototype.cloan();
}
public abstract Expression makeCompromise();
public abstract Expression makeGrade();
}
static class PCFactory extends Factory
{
public PCFactory()
{
prototype = new PCPhrase();
}
public Expression makeCompromise()
{
return new Expression("\"do it your way, any way, or no way\"");
}
public Expression makeGrade()
{
return new Expression("\"you pass, self-esteem intact\"");
}
}
static class NotPCFactory extends Factory
{
public NotPCFactory()
{
prototype = new NotPCPhrase();
}
public Expression makeCompromise()
{
return new Expression("\"my way, or the highway\"");
}
public Expression makeGrade()
{
return new Expression("\"take test, deal with the results\"");
}
}
public static void main(String[] args)
{
Factory factory;
if (args.length > 0)
factory = new PCFactory();
else
factory = new NotPCFactory();
for (int i = 0; i < 3; i++)
System.out.print(factory.makePhrase() + " ");
System.out.println();
System.out.println(factory.makeCompromise());
System.out.println(factory.makeGrade());
}
static class PCPhrase extends Expression
{
static String[] list =
{
"\"animal companion\"", "\"vertically challenged\"",
"\"factually inaccurate\"", "\"chronologically gifted\""
};
private static int next = 0;
public PCPhrase()
{
super(list[next]);
next = (next + 1) % list.length;
}
public Expression cloan()
{
return new PCPhrase();
}
}
static class NotPCPhrase extends Expression
{
private static String[] list =
{
"\"pet\"", "\"short\"", "\"lie\"", "\"old\""
};
private static int next = 0;
public NotPCPhrase()
{
super(list[next]);
next = (next + 1) % list.length;
}
public Expression cloan()
{
return new NotPCPhrase();
}
}
}
输出:
D:\Java\patterns> java FactoryFmProto
"short" "lie" "old"
"my way, or the highway"
"take test, deal with the results"
D:\Java\patterns> java FactoryFmProto 1
"vertically challenged" "factually inaccurate" "chronologically gifted"
"do it your way, any way, or no way"
"you pass, self-esteem intact"