您的位置:首页 > 其它

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

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

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



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

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

所以我们在选择这个模式的时候,一定要有一个明确的,长远的考虑,如果我们要频繁增加产品等级,建议还是不要使用这个模式。反之亦然。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: