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

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

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


这是我用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抽象工厂,可是这样一来,就违反了开闭原则。

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

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值