每一种设计模式都是为了解决一类问题而产生的,如果说工厂方法模式是针对一个产品结构而言的话,那么抽象工厂模式就是针对于多个产品结构而言的,它主要用于帮助客户一次创建多个不同的产品。
以动物园的动物为例子,老虎、海豚、鹦鹉分亚洲和非洲的。如果运用我们前一篇的工厂方法模式,那么我们就要创建大量的工厂,从而大大增加了我们的代码量,也违背了我们使用设计模式的原则。针对这个问题我们本次将讲解“抽象工厂模式”。
定义:如果客户端需要创建一些产品结构,而这些产品结构又分别属于不同的产品类别,则可以使用抽象工厂模式,抽象工厂模式中抽象工厂类负责定义创建对象的接口,这一系列对象的创建工作由实现抽象工厂的具体工厂类来具体完成。
组成:抽象工厂模式主要由4部分组成:抽象工厂类、实现抽象工厂类的具体类、抽象类和实现抽象类的具体类。
使用时机:当系统需要创建一系类相关联的对象时,就需要使用抽象工厂模式
实现代码:(篇幅有限仅以老虎类为例)
1、抽象类
//创建老虎类,实现animal借口方法
public class Tiger implements Animal {
//实现公共方法
public void eat() {
System.out.println("老虎会吃");
}
//子类特有方法
public void run(){
System.out.println("老虎会跑");
}
}
2、实现抽象老虎类
public class AfricaTiger extends Tiger{
//实现公共方法
public void eat() {
System.out.println("非洲老虎会吃");
}
//子类特有方法
public void run(){
System.out.println("非洲老虎会跑");
}
}
public class AsiaTiger extends Tiger{
//实现公共方法
public void eat() {
System.out.println("亚洲老虎会吃");
}
//子类特有方法
public void run(){
System.out.println("亚洲老虎会跑");
}
}
3、抽象工厂类
//创建工厂以及方法
public interface AbstractFactory {
Tiger createTiger();
Dolphin createDolphin();
Parrot createParrot();
}
4、具体的工厂类
//亚洲工厂
public class AsiaFactory implements AbstractFactory{
@Override
public Dolphin createDolphin() {
// TODO Auto-generated method stub
return new AsiaDolphin();
}
@Override
public Parrot createParrot() {
// TODO Auto-generated method stub
return new AsiaParrot();
}
@Override
public Tiger createTiger() {
// TODO Auto-generated method stub
return new AsiaTiger();
}
}
//创建非洲工厂
public class AfricaFactory implements AbstractFactory{
@Override
public Dolphin createDolphin() {
// TODO Auto-generated method stub
return new AfricaDolphin();
}
@Override
public Parrot createParrot() {
// TODO Auto-generated method stub
return new AfricaParrot();
}
@Override
public Tiger createTiger() {
// TODO Auto-generated method stub
return new AfricaTiger();
}
}
5、实现过程
public class Client {
public static void main(String [] args){
AbstractFactory factory = new AsiaFactory();
Tiger tiger = factory.createTiger();
tiger.eat();
factory = new AfricaFactory();
tiger = factory.createTiger();
tiger.eat();
}
}
优点:在抽象工厂模式中,客户端不再负责对象的创建,而是把这个责任交给了具体的工厂类,客户端只负责对对象的调用,从而明确了各个类的职责。
当一系列相互关联的产品被设计到一个工厂类里后,客户端的调用将会变得非常简单。而且,如果要更换这一系列的产品,只需要更换一个工厂类即可。
缺点:如果有新的产品加进来,则需要修改抽象工厂类的设计,并同时修改实现这个抽象工厂类的具体工厂类,需要额外编写代码。