设计模式之-----抽象工厂模式

来源:互联网 发布:linux find type d 编辑:程序博客网 时间:2024/06/06 01:07

今天来学习抽象工厂模式,所谓的抽象工厂,其实和工厂模式有相似之处,在介绍抽象工厂之前,先了解两个概念:产品族和产品等级

我不要官方的话解释,那样太晦涩难懂,我先给大家看一张图,看完之后我想大家能对这个概念有个了解。


这是我用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 {@Overridepublic void show() {System.out.println("福建的香蕉");}}

package com.abstractfactory.product;import com.abstractfactory.abs.product.Product;public class ProductFuJianMango extends Product {@Overridepublic 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{@Overridepublic 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 {@Overridepublic 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 {/** * 生产福建的香蕉 */@Overridepublic Product createProductBanana() {return new ProductFuJianBanana();}/** * 生产福建的芒果 */@Overridepublic 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 {/** * 生产海南的香蕉 */@Overridepublic Product createProductBanana() {return new ProductHaiNanBanana();}/** * 生产海南的芒果 */@Overridepublic 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抽象工厂,可是这样一来,就违反了开闭原则。

再来看,我们新增一个产品族,广东,这个时候,我们不必修改任何代码,只需要增加广东的相关实现即可,这个方面,又很好的实现了开闭原则。

所以我们在选择这个模式的时候,一定要有一个明确的,长远的考虑,如果我们要频繁增加产品等级,建议还是不要使用这个模式。反之亦然。



0 0