一、前言
抽象工厂模式其实是对简单工厂模式中工厂行为的一个抽象,我们不妨在这里思考一下,如果我将工厂进行抽象了,那有什么好处呢?有会有什么弊端呢?我们又如何扬长避短呢?
二、抽象工厂
我们先来谈谈什么是抽象工厂,抽象工厂模式的概述可以用如下这句话表达:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。什么意思呢?我的理解就是,这个工厂的作用就是生产一个抽象产品,而不是指定生产某种具体产品的类。举个例子,我们的工厂是一个食品工厂,这个工厂可以生产很多食品类的产品,这个时候我们工厂要对客户提供一个生产产品的接口,在这个接口中我们不知道客户到底需要什么产品,所以我们只提供一个生产食品的抽象接口,这样无论客户需要什么食品,都可以通过这个接口获取。这就是面对抽象编程的一种体现,其作用就是减少类与类之间的耦合度;减少重复代码。
如果有以下情况下可以考虑使用抽象工厂:
1.一个系统要独立于它的产品的创建、组合和表示时。
2.一个系统要由多个产品系列中的一个来配置时。
3.当你要强调一系列相关的产品对象的设计以便进行联合使用时。
4.当你提供一个产品类库,而只想显示它们的接口而不是实现时。
三、代码展示
1、创建一个抽象工厂
/**
* 提供一个一系列相关或相互依赖对象的接口
* 无需指定他们具体的类
* @author Deng
*
*/
public interface IFoodFactory {
/**
* 工厂模式提供一个创建食品的方法
* @return
*/
public Food createFood();
}
2、创建一个食物的抽象类
/**
* 1、当一个系统要独立于它的产品创建、组合和表示时
* 2、一个产品要由多个多个产品系列中的一个来配置时。
* 3、当你要强调一系列相关的产品对象的设计以便进行联合使用时
* 4、当你提供一个产品类库,而只想显示他们的接口而不是实现时
* @author Deng
*
*/
public abstract class Food {
private String price;
private String foodName;
public Food(String price, String foodName) {
super();
this.price = price;
this.foodName = foodName;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getFoodName() {
return foodName;
}
public void setFoodName(String foodName) {
this.foodName = foodName;
}
public abstract String getMessage();
}
3、创建具体的食物
/**
* 创建饼干
* @author Deng
*
*/
public class Biscuits extends Food{
public Biscuits(String price, String foodName) {
super(price, foodName);
// TODO Auto-generated constructor stub
}
@Override
public String getMessage() {
// TODO Auto-generated method stub
return this.getFoodName()+"的价格是:"+this.getPrice();
}
}
/**
* 创建面包
* @author Deng
*
*/
public class Bread extends Food{
public Bread(String price, String foodName) {
super(price, foodName);
// TODO Auto-generated constructor stub
}
@Override
public String getMessage() {
// TODO Auto-generated method stub
return "产品是:"+this.getFoodName()+"价格为:"+this.getPrice();
}
}
4、创建具体的食品工厂
/**
* 饼干工厂
* @author Deng
*
*/
public class BiscuitsFactoy implements IFoodFactory {
@Override
public Food createFood() {
// TODO Auto-generated method stub
return new Biscuits("5元", "熊仔饼干");
}
}
/**
* 面包工厂
* @author Deng
*
*/
public class BreadFactory implements IFoodFactory{
@Override
public Food createFood() {
// TODO Auto-generated method stub
return new Bread("3.5元", "面包");
}
}
public class Test {
public static void main(String[] args) {
BreadFactory breadFactory = new BreadFactory();
BiscuitsFactoy biscuitsFactory = new BiscuitsFactoy();
Food food = breadFactory.createFood();
Food food1 =biscuitsFactory.createFood();
System.out.println(food.getMessage());
System.out.println(food1.getMessage());
}
}
四、思考
首先我们思考一下,这种抽象工厂跟简单工厂比较,这种抽象工厂是不是在代码的扩展性上要比简单工厂强呢,当工厂要扩增产品的时候,我们只需要增加一个实现抽象工厂的类即可,而不需要改动源代码,这是符合开闭原则的。但是呢,这样做又有一定的弊端,因为一旦新增一个产品,我们就必须要对应增加一个工厂,可以想象一下,工厂数量的增多意味着类的增多,那么对今后代码的维护有没有影响呢?所以我们在考虑使用一个模式的时候需要权衡一下这个模式的利与弊,这主要取决与你自己设计的系统的偏向的方向,这样才有助于自己能设计出一个好地框架。