设计模式之-----抽象工厂模式
2015-07-28 10:40
218 查看
今天来学习抽象工厂模式,所谓的抽象工厂,其实和工厂模式有相似之处,在介绍抽象工厂之前,先了解两个概念:产品族和产品等级
我不要官方的话解释,那样太晦涩难懂,我先给大家看一张图,看完之后我想大家能对这个概念有个了解。
这是我用Visio画的,从这个图看,是不是很直观的看出他们的定义呢?
由不同的产品等级的产品构成了一个产品组。他们之间大概就是这个关系。
然后回到抽象工厂模式,我们根据代码,来看一看是一个怎样的步骤,用文字叙述半天也不如直接看代码来的快。我还是用上边的例子。
先看包结构:
我们首先要做的,就是新建一个抽象类(接口也可以)
因为这个例子有四个实际的产品,那么我们新建四个类,继承上边的抽象类(或实现接口)
好了,四个类写完了,之后我们在建一个抽象类(接口也可以)
然后,根据产品族,来将四个实例划分一下
到现在,抽象工厂已经写完了,是不是很简单啊?最后来个测试类
最后结果:
那么我们回头思考一下,这个模式有没有缺点呢?当然有,假设一下,现在我们新增了一个西瓜,怎么修改呢?我们肯定要修改之前的ProductCreater抽象工厂,可是这样一来,就违反了开闭原则。
再来看,我们新增一个产品族,广东,这个时候,我们不必修改任何代码,只需要增加广东的相关实现即可,这个方面,又很好的实现了开闭原则。
所以我们在选择这个模式的时候,一定要有一个明确的,长远的考虑,如果我们要频繁增加产品等级,建议还是不要使用这个模式。反之亦然。
我不要官方的话解释,那样太晦涩难懂,我先给大家看一张图,看完之后我想大家能对这个概念有个了解。
这是我用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抽象工厂,可是这样一来,就违反了开闭原则。
再来看,我们新增一个产品族,广东,这个时候,我们不必修改任何代码,只需要增加广东的相关实现即可,这个方面,又很好的实现了开闭原则。
所以我们在选择这个模式的时候,一定要有一个明确的,长远的考虑,如果我们要频繁增加产品等级,建议还是不要使用这个模式。反之亦然。
相关文章推荐
- POJ 1065:Wooden Sticks
- mysql取time ,datetime字段显示问题
- SpringMVC详解(一)简介
- css居中总结
- hdu1535 SPFA
- POJ 3648 2-sat
- iOS Sprite Kit教程之场景的切换
- CSS3实现动态背景登录框的代码
- 年轻程序员的悲伤
- TCP and UDP Small Servers
- MbrFix的用法
- 开放还是封闭?一个值得考虑的问题
- 判断两个二叉树是否相同
- Hotel - poj 3667(求连续子区间)
- LeetCode Reverse Nodes in k-Group 每k个节点为一组,反置链表
- Mac zend studio 12.0.2 破解汉化
- Apache Shiro 使用手册(三)Shiro 授权
- 机房收费系统——上下机
- js 验证div 下的元素
- 使用 TestLink 进行测试管理