抽象工厂模式是对工厂模式在产品扩展上的抽象化。抽象化的目的是为了对产品特性进行扩展。
比如,先前,我们的产品接口是这样:
public interface Product {
public void doSomething();
}
现在要扩展产品新特性:
public interface Product {
public void doSomething();
public void doOtherthing();
}
但是,这并不算完。在工厂模式的结构上还要做变化。原来的工厂模式结构是这样:
一个抽象产品(接口或者抽象类)
几个具体的产品类去实现这个抽象产品
一个工厂类
一个调用类
现在要变成这样:
一个抽象产品(接口或者抽象类)
几个产品抽象类去实现产品接口
几个产品具体类去分别继承这几个产品抽象类
一个工厂接口
一个工厂抽象类
几个新特性的工厂实现类去实现工厂接口
一个调用类
那意味着你的结构是这样:
产品抽象类
public abstract class AbstractProductA implements Product {
@Override
public void doSomething() {
System.out.println("Abstract Product A do something.");
}
}
public abstract class AbstractProductB implements Product {
@Override
public void doSomething() {
System.out.println("Abstract Product B do something.");
}
}
拥有新特性的产品具体类:
public class ProductANewFeature extends AbstractProductA {
@Override
public void doOtherthing() {
System.out.println("Product A do otherthing.");
}
}
public class ProductBNewFeature extends AbstractProductB {
@Override
public void doOtherthing() {
System.out.println("Product B do otherthing.");
}
}
如果,这个新特性有很多个值,那么,这里的ProductA和ProductB要分别写成ProductANewFeature1和ProductANewFeature2这样,以此类推。
public interface Factory {
public Product createProductA();
public Product createProductB();
}
抽象的工厂类
public abstract class AbstractProductFactory implements Factory {
protected Product createProduct(Class c) {
Product prod = null;
try {
prod = (Product) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO: handle exception
}
return prod;
}
}
工厂的具体实现类(加入新特性的)
public class NewFeatureProductFactory extends AbstractProductFactory {
@Override
public Product createProductA() {
return super.createProduct(ProductANewFeature.class);
}
@Override
public Product createProductB() {
return super.createProduct(ProductBNewFeature.class);
}
}
public class FactoryCaller {
public static void main(String[] args) {
Product prodA = ProductFactory.createProduct(ProductA.class);
prodA.doSomething();
Product prodB = ProductFactory.createProduct(ProductB.class);
prodB.doSomething();
}
}
现在改成这样:
public class FactoryCaller {
public static void main(String[] args) {
Factory f = new NewFeatureProductFactory();
Product prodA = f.createProductA();
Product prodB = f.createProductB();
prodA.doOtherthing();
prodB.doOtherthing();
}
}
从上面看以看出,如果想要保持对产品特性的扩展有一个灵活的扩展结构的话,无疑抽象工厂模式是最合适的。而工厂模式只能适用于简单的情况。
那么,基于这个结构,该如何做泛型化处理呢?
在这个模式里,工厂是负责生产产品的。不难理解,应该将工厂部分做泛型化处理。
在这之前,我们要将结构稍作调整:
加一个抽象产品类
public abstract class AbstractProduct implements Product {
}
然后AbstractProductA和AbstractProductB分别继承此类。
public abstract class AbstractProductA extends AbstractProduct {
@Override
public void doSomething() {
System.out.println("Abstract Product A do something.");
}
}
public abstract class AbstractProductB extends AbstractProduct {
@Override
public void doSomething() {
System.out.println("Abstract Product B do something.");
}
}
没泛型化之前,涉及到工厂的代码如下:
工厂接口
public interface Factory {
public T createProductA();
public T createProductB();
}
抽象工厂
public abstract class AbstractProductFactory implements Factory {
protected Product createProduct(Class c) {
Product prod = null;
try {
prod = (Product) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO: handle exception
}
return prod;
}
}
具体工厂
public class NewFeatureProductFactory extends AbstractProductFactory {
@Override
public Product createProductA() {
return super.createProduct(ProductANewFeature.class);
}
@Override
public Product createProductB() {
return super.createProduct(ProductBNewFeature.class);
}
}
泛型化之后:
工厂接口
public interface Factory<T extends AbstractProduct> {
public T createProductA();
public T createProductB();
}
抽象工厂
@SuppressWarnings("all")
public abstract class AbstractProductFactory<T extends AbstractProduct> implements Factory<T> {
protected T createProduct(Class<? extends AbstractProduct> c) {
T prod = null;
try {
prod = (T) Class.forName(c.getName()).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
return prod;
}
}
具体工厂
public class NewFeatureProductFactory<T extends AbstractProduct> extends AbstractProductFactory<T> {
@Override
public T createProductA() {
return super.createProduct(ProductANewFeature.class);
}
@Override
public T createProductB() {
return super.createProduct(ProductBNewFeature.class);
}
}
最后的调用像这样:
public class FactoryCaller {
public static void main(String[] args) {
Factory<ProductANewFeature> f = new NewFeatureProductFactory<ProductANewFeature>();
Product prodA = f.createProductA();
Factory<ProductBNewFeature> f2 = new NewFeatureProductFactory<ProductBNewFeature>();
Product prodB = f2.createProductB();
prodA.doOtherthing();
prodB.doOtherthing();
}
}
这里主要理解下类型限定就好了。