今天来学习抽象工厂模式,所谓的抽象工厂,其实和工厂模式有相似之处,在介绍抽象工厂之前,先了解两个概念:产品族和产品等级
我不要官方的话解释,那样太晦涩难懂,我先给大家看一张图,看完之后我想大家能对这个概念有个了解。
这是我用Visio画的,从这个图看,是不是很直观的看出他们的定义呢?
由不同的产品等级的产品构成了一个产品组。他们之间大概就是这个关系。
然后回到抽象工厂模式,我们根据代码,来看一看是一个怎样的步骤,用文字叙述半天也不如直接看代码来的快。我还是用上边的例子。
先看包结构:
我们首先要做的,就是新建一个抽象类(接口也可以)
package com.abstractfactory.abs.product;
/**
* 所有产品的抽象类
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public abstract class Product {
/**
* 显示产品的名称
*/
public abstract void show();
}
因为这个例子有四个实际的产品,那么我们新建四个类,继承上边的抽象类(或实现接口)
package com.abstractfactory.product;
import com.abstractfactory.abs.product.Product;
/**
* 福建的香蕉
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public class ProductFuJianBanana extends Product {
@Override
public void show() {
System.out.println("福建的香蕉");
}
}
package com.abstractfactory.product;
import com.abstractfactory.abs.product.Product;
public class ProductFuJianMango extends Product {
@Override
public void show() {
System.out.println("福建的芒果");
}
}
package com.abstractfactory.product;
import com.abstractfactory.abs.product.Product;
/**
* 海南的香蕉
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public class ProductHaiNanBanana extends Product{
@Override
public void show() {
System.out.println("海南的香蕉");
}
}
package com.abstractfactory.product;
import com.abstractfactory.abs.product.Product;
/**
* 海南的芒果
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public class ProductHaiNanMango extends Product {
@Override
public void show() {
System.out.println("海南的芒果");
}
}
好了,四个类写完了,之后我们在建一个抽象类(接口也可以)
package com.abstractfactory.abs.creater;
import com.abstractfactory.abs.product.Product;
/**
* 根据产品族来区分
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public abstract class ProductCreater {
/**
* 生产香蕉,这里不对产品等级区分
* @return
*/
public abstract Product createProductBanana();
/**
* 生产芒果,这里不对产品等级区分
* @return
*/
public abstract Product createProductMango();
}
然后,根据产品族,来将四个实例划分一下
package com.abstractfactory.creater;
import com.abstractfactory.abs.creater.ProductCreater;
import com.abstractfactory.abs.product.Product;
import com.abstractfactory.product.ProductFuJianBanana;
import com.abstractfactory.product.ProductFuJianMango;
/**
* 只生产福建的产品
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public class CreateByFuJian extends ProductCreater {
/**
* 生产福建的香蕉
*/
@Override
public Product createProductBanana() {
return new ProductFuJianBanana();
}
/**
* 生产福建的芒果
*/
@Override
public Product createProductMango() {
return new ProductFuJianMango();
}
}
package com.abstractfactory.creater;
import com.abstractfactory.abs.creater.ProductCreater;
import com.abstractfactory.abs.product.Product;
import com.abstractfactory.product.ProductHaiNanBanana;
import com.abstractfactory.product.ProductHaiNanMango;
/**
* 只生产海南的产品
* @author ZHENGWEI
* @date Jul 28, 2015
*/
public class CreateByHaiNan extends ProductCreater {
/**
* 生产海南的香蕉
*/
@Override
public Product createProductBanana() {
return new ProductHaiNanBanana();
}
/**
* 生产海南的芒果
*/
@Override
public Product createProductMango() {
return new ProductHaiNanMango();
}
}
到现在,抽象工厂已经写完了,是不是很简单啊?最后来个测试类
package com.abstractfactory.main;
import com.abstractfactory.abs.creater.ProductCreater;
import com.abstractfactory.creater.CreateByFuJian;
import com.abstractfactory.creater.CreateByHaiNan;
public class AbstractFactoryMain {
public static void main(String[] args) {
//福建
ProductCreater createrF = new CreateByFuJian();
createrF.createProductBanana().show();
createrF.createProductMango().show();
//海南
ProductCreater createrH = new CreateByHaiNan();
createrH.createProductBanana().show();
createrH.createProductMango().show();
}
}
最后结果:
那么我们回头思考一下,这个模式有没有缺点呢?当然有,假设一下,现在我们新增了一个西瓜,怎么修改呢?我们肯定要修改之前的ProductCreater抽象工厂,可是这样一来,就违反了开闭原则。
再来看,我们新增一个产品族,广东,这个时候,我们不必修改任何代码,只需要增加广东的相关实现即可,这个方面,又很好的实现了开闭原则。
所以我们在选择这个模式的时候,一定要有一个明确的,长远的考虑,如果我们要频繁增加产品等级,建议还是不要使用这个模式。反之亦然。