Java设计模式之抽象工厂模式
一、定义
抽象工厂模式提供了一个接口,用于创建相关或相依赖对象的家族,而不需要指定具体实现类
抽象工厂模式允许客户使用抽象接口来创建一组相关的产品,客户类和工厂类分开,客户需要任何产品的时候,只需要向工厂请求即可,客户无需修改就可以获得新产品,这样一来,客户就从具体产品中解耦
二、实现
抽象产品
package net.cn.as.product;
/**
* 抽象产品类
* @author chenas
* 2013.08.24
*/
public abstract class AbstractBaseProduct {
protected String name;
protected String strDate;
public String getName(){
return this.name;
}
}
产品接口
package net.cn.as.product;
/**
* 产品接口
* @author chenas
* 2013.08.24
*/
public interface IProduct {
public void printMsg();
}
不同产品的抽象基类
package net.cn.as.product;
/**
* 产品A基类
* @author chenas
*
*/
public class ProductA extends AbstractBaseProduct implements IProduct{
@Override
public void printMsg() {
System.out.println(this.name +" "+this.strDate);
}
}
package net.cn.as.product;
/**
* 产品B基类
* @author chenas
*
*/
public class ProductB extends AbstractBaseProduct implements IProduct{
@Override
public void printMsg() {
System.out.println(this.name +" "+this.strDate);
}
}
package net.cn.as.product;
/**
* 产品C基类
* @author chenas
*
*/
public class ProductC extends AbstractBaseProduct implements IProduct{
@Override
public void printMsg() {
System.out.println(this.name +" "+this.strDate);
}
}
具体产品
package net.cn.as.product;
/**
* 产品A
* @author chenas
*
*/
public class ProductAA extends ProductA{
public ProductAA(){
this.name="AA";
this.strDate="2013.08.24";
}
}
package net.cn.as.product;
/**
* 产品B
* @author chenas
*
*/
public class ProductBB extends ProductB{
public ProductBB(){
this.name = "BB";
this.strDate = "2013.08.25";
}
}
package net.cn.as.product;
/**
* 产品C基类
* @author chenas
*
*/
public class ProductCC extends ProductC{
public ProductCC(){
this.name = "CC";
this.strDate = "2013.08.26";
}
}
工厂接口
package net.cn.as.factory;
import net.cn.as.product.ProductA;
import net.cn.as.product.ProductB;
import net.cn.as.product.ProductC;
/**
* 工厂接口
* @author chenas
*
*/
public interface IFactory {
public ProductA cteateProductA();
public ProductB cteateProductB();
public ProductC cteateProductC();
}
工厂实现
package net.cn.as.factory;
import net.cn.as.product.ProductA;
import net.cn.as.product.ProductAA;
import net.cn.as.product.ProductB;
import net.cn.as.product.ProductBB;
import net.cn.as.product.ProductC;
import net.cn.as.product.ProductCC;
/**
* 工厂实现
* @author chenas
*
*/
public class Factory implements IFactory{
@Override
public ProductA cteateProductA() {
return new ProductAA();
}
@Override
public ProductB cteateProductB() {
return new ProductBB();
}
@Override
public ProductC cteateProductC() {
return new ProductCC();
}
}
package net.cn.as.client;
import net.cn.as.factory.IFactory;
import net.cn.as.product.ProductA;
import net.cn.as.product.ProductB;
import net.cn.as.product.ProductC;
/**
* 客户类
* @author chenas
*
*/
public class Client {
public IFactory factory;
public Client(IFactory factory){
this.factory = factory;
}
public void getProductA(){
ProductA a = this.factory.cteateProductA();
a.printMsg();
}
public void getProductB(){
ProductB b = this.factory.cteateProductB();
b.printMsg();
}
public void getProductC(){
ProductC c = this.factory.cteateProductC();
c.printMsg();
}
}
package net.cn.as.test;
import net.cn.as.client.Client;
import net.cn.as.factory.Factory;
import net.cn.as.factory.IFactory;
public class MainApp {
/**
* @param args
*/
public static void main(String[] args) {
IFactory factory = new Factory();
Client client = new Client(factory);
client.getProductA();
client.getProductB();
client.getProductC();
}
}
输出结果
AA 2013.08.24
BB 2013.08.25
CC 2013.08.26
三、设计原则
1、多用对象组合,少用继承
让对象成为类的成员变量,通过构造函数或set方法对给类对象实例的变量赋值
2、针对抽象编程,不针对实现编程
抽象编程能提高代码的复用
3、产品对象通过工厂暴露的方法创建
高内聚低耦合,降低对象间的耦合
四、使用场合
1、创建产品家族,相关产品集合在一起使用的时候
2、想要提供一个产品类库,并只想显示其接口而不是实现时
3、通过组合方式使用工厂时
五、与工厂方法模式的简单比较
1、相同点
都是工厂模式,实现了将应用程序从特定的实现类中解耦
2、不同点
工厂方法模式通过继承的方式实现应用程序的解耦,而抽象工厂模式则通过对象组合的方式实现应用程序解耦;
工厂方法模式用来创建一个抽象产品,具体工厂实现工厂方法来创建具体产品,而抽象工厂模式用来创建一个产品家族的抽象类型。