设计模式-工厂方法模式扩展

对于工厂方法模式有4中扩展形式

对于这几种扩展不变的类:

Person类:

package com.feng.factory.Person;

public abstract class Person {
	public abstract void getColor();
	public abstract void talk();

}
WhitePerson类:

package com.feng.factory.Person;

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("白种人说话了");

	}

}
BlackPerson类:

package com.feng.factory.Person;

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("黑种人说话了");

	}

}
YellowPerson类:

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;

public class YellowPersonFactory implements PersonFactory {

	@Override
	public Person create() {
		// TODO Auto-generated method stub
		return new YellowPerson();
	}

}
BlackPersonFactory类:

package com.feng.factory.Person;

public class BlackPersonFactory implements PersonFactory {

	@Override
	public Person create() {
		// TODO Auto-generated method stub
		return new BlackPerson();
	}

}
WhitePersonFactory类:

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;

public class Car {

	private Car()
	{
		
	}
	
	public void run()
	{
		System.out.println("车开动。。。。");
	}
}
SingletonFactory类

package com.feng.factory.singleton;

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;
	}
	
	
}
测试类Test:

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;

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;
	}

}
测试类Test

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连接池就是这种思想




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值