1、定义

     • 在简单工厂模式中,可以根据参数的不同返回不同类型的实例,简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。 

2、要点

     • 当客户端需要什么,只要传入一个正确的参数,即可获取需要的实例,无需知道其创建的细节

     • 客户端不知道具体实现的是什么,也不知道如何实现,只知道可以通过一个工厂获取一个对象,然后通过这个对象获取想要的功能

3、何时选用单例模式

     • 想完全隔离实现,让外部只能通过接口来操作封装体

     • 想把对外创建对象的职责进行集中管理和控制

4、本质

     • 选择实现

5、简单工厂模式实现方式

     • Product接口  

package com.test;

/**
* 接口的定义,该接口可以通过简单工厂来创建
*/
public interface Product 
{
	/**
	* 示意,具体的功能方法的定义
	* @param s 示意,需要的参数
	*/
	public void test(String s);
}

 

  • 具体的实现类A

package com.test;

/**
* 接口的具体实现对象TestA
*/
public class ConcreteProductA implements Product{

	@Override
	public void test(String s) {
		// TODO Auto-generated method stub
		System.out.println("ConccreteProductA:============"+s);
	}

}

  • 具体的实现类B

package com.test;

/**
* 接口的具体实现对象TestB
*/
public class ConcreteProductB implements Product{

	@Override
	public void test(String s) {
		// TODO Auto-generated method stub
		System.out.println("ConccreteProductB:============"+s);
	}

}

  • 配置文件Properties

TestA=com.test.ConccreteProductA

  • 工厂类

package com.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
* 工厂类,用来创造Api对象
*/
public class Factory {

	/**
	* 具体的创造TestAbstract对象的方法
	* @param condition 示意,从外部传入的选择条件
	* @return 创造好的TestAbstract对象
	*/
	public static Product createApi(int condition)
	{
		//应该根据某些条件去选择究竟创建哪一个具体的实现对象,
		//这些条件可以从外部传入,也可以从其它途径获取。
		//如果只有一个实现,可以省略条件,因为没有选择的必要。
		//示意使用条件
		Product api = null;
		if(condition == 1)
		{
			api = new ConcreteProductA();
		}
		else if(condition == 2)
		{
			api = new ConcreteProductB();
		}
		return api;
	}
	
	/**
	* 具体的创造TestAbstract的方法,根据配置文件的参数来创建接口
	* @return 创造好的TestAbstract对象
	*/
	public static Product createApi()
	{
		//直接读取配置文件来获取需要创建实例的类
		//至于如何读取Properties,还有如何反射这里就不解释了
		Properties p = new Properties();
		InputStream in = null;
		try 
		{
			in = Factory.class.getResourceAsStream(
			"TestFactory.properties");
			p.load(in);
		} catch (IOException e) {
			System.out.println(
			"装载工厂配置文件出错了,具体的堆栈信息如下:");
			e.printStackTrace();
		}
		finally
		{
			try {
				in.close();
			} catch (IOException e) 
			{
				e.printStackTrace();
			}
		}
		//用反射去创建,那些例外处理等完善的工作这里就不做了
		Product api = null;
		try 
		{
			api = (Product)Class.forName(p.getProperty("TestA")).newInstance();
		} 
		catch (InstantiationException e) {
			e.printStackTrace();
		}
		catch (IllegalAccessException e) {
			e.printStackTrace();
		} 
		catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return api;
	}
}

  说明:外部在调用工厂类进行创建对象时,主要是通过两个方法,如下

              1)Product testa=Factory.createApi(1);此方法外部是通过传入参数,工厂类根据参数进行选择具体的实现,调用方只知道Product父类,以及参数

              2)Product api = Factory.createApi();此方法是通过配置文件来进行选择的,调用端不知道具体实现,也不知道参数,只知道返回的是一个Product对象,选择则是通过配置文件来完成

              3)有人可能会说,工厂类中用到了new,知道了具体的实现的,但是注意工厂类的位置,工厂类是于product在同一个包中的,即地位是相同的,都属于内部,而工厂类是内部提供给外部使用的,因此工厂类知道具体实现是OK的

 

posted on 2014-11-04 18:55  暖 暖  阅读(438)  评论(0编辑  收藏  举报