2 工厂模式
2.1 工厂模式的几种形态
工厂模式专门负责将大量有共同接口的类实例化。工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类,工厂模式有以下几种形态:(1) 简单工厂模式:又称静态工厂方法模式。
(2) 工厂方法模式:又称多态性工厂模式或虚拟构造子模式。
(3) 抽象工厂模式:又称工具箱模式。
2.2 简单工厂模式
简单工厂模式的简略类图如下所示:
(1) 工厂类角色:担任这个角色的是工厂方法模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体Java类实现。
(2) 抽象产品角色:担任这个角色的类是由工厂方法模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个Java接口或者Java抽象类实现。
(3) 具体产品角色:工厂方法模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体Java类实现。
抽象产品角色可以是一个Java接口,也可以是一个Java抽象类,实际使用中,当多个产品类之间没有共同的业务逻辑时,抽象产品角色用接口实现;当多个产品类之间有共同的业务逻辑时,通常把这些业务逻辑放置到抽象类里面,而这个抽象类同时作为抽象产品角色。
2.2.1 标准工厂方法模式
(1) 第一个抽象产品角色-抽象类
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.abst;
/**
* 抽象产品-抽象类
*
* @author Geloin
*
*/
public abstract class ProductAbst {
/**
* 测试方法
*
* @author Geloin
*/
public abstract void sayHello();
}
(2) 第二个抽象产品角色-接口
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.intf;
/**
* 抽象产品-接口
*
* @author Geloin
*
*/
public interface ProductIntf {
/**
* 测试方法
*
* @author Geloin
*/
public void sayHello();
}
(3) 具体产品角色
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.abst;
/**
* 继承了抽象类的具体产品
*
* @author Geloin
*/
public class ConcreteProductA1 extends ProductAbst {
/*
* (non-Javadoc)
*
* @see com.geloin.pattern.factory.simple.ProductAbst#sayHello()
*/
@Override
public void sayHello() {
System.out.println("Concrete Product Abst say hello.");
}
}
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.abst;
/**
* @author Geloin
*
*/
public class ConcreteProductA2 extends ProductAbst {
/*
* (non-Javadoc)
*
* @see com.geloin.pattern.factory.simple.abst.ProductAbst#sayHello()
*/
@Override
public void sayHello() {
System.out
.println("I don't want to say hello because I am ConcreteProductA2.");
}
}
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.intf;
/**
* 实现了产品接口的具体产品
*
* @author Geloin
*
*/
public class ConcreteProductB1 implements ProductIntf {
/*
* (non-Javadoc)
*
* @see com.geloin.pattern.factory.simple.ProductIntf#sayHello()
*/
@Override
public void sayHello() {
System.out.println("Concrete Product Intf say hello");
}
}
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.intf;
/**
* @author Geloin
*
*/
public class ConcreteProductB2 implements ProductIntf {
/*
* (non-Javadoc)
*
* @see com.geloin.pattern.factory.simple.intf.ProductIntf#sayHello()
*/
@Override
public void sayHello() {
System.out.println("I must say hello because I am ConcreteProductB2.");
}
}
(4) 工厂类角色
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard.factory;
import com.geloin.pattern.factory.simple.standard.abst.ConcreteProductA1;
import com.geloin.pattern.factory.simple.standard.abst.ConcreteProductA2;
import com.geloin.pattern.factory.simple.standard.abst.ProductAbst;
import com.geloin.pattern.factory.simple.standard.intf.ConcreteProductB1;
import com.geloin.pattern.factory.simple.standard.intf.ConcreteProductB2;
import com.geloin.pattern.factory.simple.standard.intf.ProductIntf;
/**
* @author Geloin
*
*/
public class Creator {
/**
* 针对抽象类的工厂
*
* @author Geloin
* @return
*/
public static ProductAbst factoryA1() {
return new ConcreteProductA1();
}
/**
* 针对抽象类的工厂
*
* @author Geloin
* @return
*/
public static ProductAbst factoryA2() {
return new ConcreteProductA2();
}
/**
* 针对接口的工厂
*
* @author Geloin
* @return
*/
public static ProductIntf factoryB1() {
return new ConcreteProductB1();
}
/**
* 针对接口的工厂
*
* @author Geloin
* @return
*/
public static ProductIntf factoryB2() {
return new ConcreteProductB2();
}
}
(5) 测试类
/**
* @author Geloin
*/
package com.geloin.pattern.factory.simple.standard;
import junit.framework.Assert;
import org.junit.Test;
import com.geloin.pattern.factory.simple.standard.abst.ConcreteProductA1;
import com.geloin.pattern.factory.simple.standard.abst.ConcreteProductA2;
import com.geloin.pattern.factory.simple.standard.abst.ProductAbst;
import com.geloin.pattern.factory.simple.standard.factory.Creator;
import com.geloin.pattern.factory.simple.standard.intf.ConcreteProductB1;
import com.geloin.pattern.factory.simple.standard.intf.ConcreteProductB2;
import com.geloin.pattern.factory.simple.standard.intf.ProductIntf;
/**
* @author Geloin
*
*/
public class Main {
/**
* 测试方法
* @author Geloin
*/
@Test
public void test() {
ProductAbst abst = Creator.factoryA1();
abst.sayHello();
Assert.assertTrue(abst instanceof ConcreteProductA1);
abst = Creator.factoryA2();
abst.sayHello();
Assert.assertTrue(abst instanceof ConcreteProductA2);
ProductIntf intf = Creator.factoryB1();
intf.sayHello();
Assert.assertTrue(intf instanceof ConcreteProductB1);
intf = Creator.factoryB2();
intf.sayHello();
Assert.assertTrue(intf instanceof ConcreteProductB2);
}
}