对于工厂方法模式有4中扩展形式
对于这几种扩展不变的类:
Person类:
package com.feng.factory.Person;WhitePerson类:
public abstract class Person {
public abstract void getColor();
public abstract void talk();
}
package com.feng.factory.Person;BlackPerson类:
public class WhitePerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是白种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("白种人说话了");
}
}
package com.feng.factory.Person;YellowPerson类:
public class BlackPerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是黑种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("黑种人说话了");
}
}
package com.feng.factory.Person;
public class YellowPerson extends Person {
@Override
public void getColor() {
// TODO Auto-generated method stub
System.out.println("我是黄种人");
}
@Override
public void talk() {
// TODO Auto-generated method stub
System.out.println("黄种人说话了");
}
}
(1)缩小为简单工厂模式
如果一个模块仅需要一个工厂类,那么工厂类就不需要一个接口了。直接一个工厂实现类即可,把工厂类的方法改为static方法,对于上一篇的内容修改如下:
AllPersonFactory类:
package com.feng.factory.Person;那么测试类也需要跟着改
public class AllPersonFactory {
public static <T extends Person> T create(Class<T> c) {
// TODO Auto-generated method stub
Person person = null;
try {
person = (T)Class.forName(c.getName()).newInstance();
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("创造人失败");
}
return (T)person;
}
}
package com.feng.factory.Person;这种模式是工厂模式的弱化,因为简单,所以又叫简单工厂模式,也叫静态工厂模式
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person p = AllPersonFactory.create(YellowPerson.class);
p.talk();
p.getColor();
}
}
缺点是工厂类的扩建非常困难,想想就知道了,没有一个统一的接口,如果添加一个工厂类会引起大量代码的改动
(2)升级为多个工厂
这一点其实在上一篇文章中已经用到了,就是在工厂类中不使用java的反射机制,而是为每一个人种都提供一个工厂的实现类
首先,提供一个借口:
package com.feng.factory.Person;分别定义三个工厂实现这个接口
public interface PersonFactory {
Person create();
}
YellowPersonFactory类:
package com.feng.factory.Person;BlackPersonFactory类:
public class YellowPersonFactory implements PersonFactory {
@Override
public Person create() {
// TODO Auto-generated method stub
return new YellowPerson();
}
}
package com.feng.factory.Person;WhitePersonFactory类:
public class BlackPersonFactory implements PersonFactory {
@Override
public Person create() {
// TODO Auto-generated method stub
return new BlackPerson();
}
}
package com.feng.factory.Person;测试类如下:
public class WhitePersonFactory implements PersonFactory {
@Override
public Person create() {
// TODO Auto-generated method stub
return new WhitePerson();
}
}
package com.feng.factory.Person;这种模式职责清晰,结构简单,但是给扩展性和可维护性带来一定的影响。因为工厂类和人种类数量是相同的,维护时需要考虑两个对象之间的关系。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
PersonFactory factory = new YellowPersonFactory();
Person p = factory.create();
p.talk();
p.getColor();
}
}
(3)替代单例模式
使用工厂方法模式,用过反射机制来实现单例模式
这里使用car来举例:
car类
package com.feng.factory.singleton;SingletonFactory类
public class Car {
private Car()
{
}
public void run()
{
System.out.println("车开动。。。。");
}
}
package com.feng.factory.singleton;测试类Test:
import java.lang.reflect.Constructor;
public class SingletonFactory {
private static Car car;
//利用反射机制实现单例
static
{
try
{
Class c1 = Class.forName(Car.class.getName());
//获得无参的构造方法
Constructor constructor = c1.getDeclaredConstructor();
//设置无参的构造方法是可以访问的
constructor.setAccessible(true);
//产生一个实例独享
car = (Car)constructor.newInstance();
}
catch(Exception e)
{
System.out.println("获取单例失败。。。");
}
}
public static Car getInstance()
{
return car;
}
}
package com.feng.factory.singleton;如果给工厂传递一个参数的话,该模式可以产生任何类的单例
public class Test {
public static void main(String[] args)
{
Car car1 = SingletonFactory.getInstance();
Car car2 = SingletonFactory.getInstance();
if(car1 == car2)
{
System.out.println("same class");
}
}
}
(4)延迟初始化
在工厂中,对象用完之后可以不立即销毁,而是保留其初始状态,方便对象再次被用到,其实就是用一个集合类,将对象保存下来
简单模拟一个小例子:使用蚊帐开头的三个类,
工厂类AllPersonFactory
package com.feng.factory.lazy;测试类Test
import java.util.HashMap;
import java.util.Map;
public class AllPersonFactory {
//缓存,用来存储对象
private static final Map<String, Person> personMap = new HashMap();
public static Person create(String type) {
Person person = null;
if(personMap.containsKey(type))
{
person = personMap.get(type);
}
else
{
if(type.equals("Yellow"))
{
person = new YellowPerson();
}
else if(type.equals("Black"))
{
person = new BlackPerson();
}
else
{
person = new WhitePerson();
}
personMap.put(type, person);
}
return person;
}
}
package com.feng.factory.lazy;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
Person person = AllPersonFactory.create("Yellow");
Person person1 = AllPersonFactory.create("Yellow");
person.talk();
person.getColor();
if(person == person1)
{
System.out.println("same");
}
}
}
这种模式是可以扩展的,比如实现成受限的多例模式,JDBC连接池就是这种思想