一. 与工厂模式的区别
工厂模式:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
关于抽象工厂,我是这样理解的,抽象工厂更像是简单工厂模式的高级版,简单工厂模式只能生产一类产品的多个型号,而抽象工厂能生产不同类别的产品。举个例子,一家水果店只卖苹果,有红富士,还有嘎啦果。如果想卖梨子,就得重新开一家水果店了(新建一个工厂类)。可能有人会有疑问,为什么不重新装修一下卖苹果的店子,让它也能卖梨子?事实是为了遵循oop中的开闭原则,在扩展时一般不会去直接修改源代码。这个时候抽象工厂就能很好的解决问题了。
现在,我们把水果店当作一个抽象工厂,店内的卖不同水果的柜台当作实际售卖水果的工厂。如果有新类目水果增加,我们只需要在水果店(抽象工厂)内增加一个新柜台(售卖水果的工厂类),柜台就可以卖该种水果的不同类型了。
二. 具体实现
该图是菜鸟教程上的一张图,下面的具体实现和上面这张图的结构一样,所以就懒得重新画一遍了。
1.先创建一个超级工厂,也就是我们果蔬店
public abstract class AbstractFactory {
public abstract Fruit getFruit(String name);
public abstract Vegetables getVegetables(String name);
}
2.水果店有了,接下来该创建卖具体果蔬的的柜台
public class VegetablesFactory extends AbstractFactory {
@Override
public Fruit getFruit(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public Vegetables getVegetables(String name) {
// TODO Auto-generated method stub
if(name=="tomato") {
return new Tomato();
}
if(name=="eggplant") {
return new Eggplant();
}
return null;
}
}
public class FruitFactory extends AbstractFactory{
@Override
public Fruit getFruit(String name) {
// TODO Auto-generated method stub
if(name=="apple") {
return new Apple();
}
if(name=="banana") {
return new Banana();
}
return null;
}
@Override
public Vegetables getVegetables(String name) {
// TODO Auto-generated method stub
return null;
}
}
3.这一步和简单工厂模式一样,创建柜台售卖的具体物品(接口+实现类)。接口:水果,蔬菜。实现类:苹果,香蕉,茄子,西红柿。
public interface Fruit {
void desc();
}
public class Apple implements Fruit {
@Override
public void desc() {
System.out.println("我是苹果");
}
}
public class Banana implements Fruit {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("我是香蕉");
}
}
public interface Vegetables {
public void desc();
}
public class Eggplant implements Vegetables {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("我是茄子");
}
}
public class Tomato implements Vegetables {
@Override
public void desc() {
// TODO Auto-generated method stub
System.out.println("我是番茄");
}
}
4.果蔬店和商品都有了,顾客就可以来买了。
public class Test {
public static void main(String[] args) {
AbstractFactory factory = new FruitFactory();
Fruit fruit = factory.getFruit("apple");
fruit.desc();
}
}
优点:当一个产品族中的多个对象被设计成一起工作时,它能保证客户端始终只使用同一个产品族中的对象。
缺点:产品族扩展非常困难,要增加一个系列的某一产品,既要在抽象的 Creator 里加代码,又要在具体的里面加代码。
使用场景: 1、QQ 换皮肤,一整套一起换。 2、生成不同操作系统的程序。
注意事项:产品族难扩展,产品等级易扩展。