全局實例框架的設計

1、全局實例

全局實例:Global Instance

一直存在的、不會被GC回收銷燬的對象

一般使用public static來創建一個全局實例

演示一下:

1、創建全局實例

public static Car car = new Car();

2、訪問全局實例

AfGlobals.car.run();

在任何時候都可以訪問,在任何地點都可以訪問

代碼演示(方便理解記憶)(1.0)

3個普通類:

public class Car
{
	public void run()
	{
		System.out.println("汽車....");
	}
}
public class Plane
{
	public void fly()
	{
		System.out.println("飛機飛....");
	}
}
public class Train
{
	public void speed()
	{
		System.out.println("火車....");
	}
}

全局對象類:

public class AfGlobal
{
	public static Car car = new Car();
	
	public static Plane plane = new Plane();
	
	public static Train train = new Train();
}

測試類:

public class Test
{

	public static void main(String[] args)
	{
		AfGlobal.car.run();
		
		AfGlobal.plane.fly();
		
		AfGlobal.train.speed();
	}

}

2、全局實例管理

AfGlobals,負責全局實例的管理

項目裏所需要的全局實例,都交給它創建和管理

繼續看代碼(升級) (1.1)

將所有的實例放到一個Map中,當需要實例的時候,初始化執行一次,然後通過get直接獲取value

- 在AfGlobals創建所有全局實例,放在map中

- 每個全局實例關聯一個唯一的名字

- 在使用的時候,按名字取出 

實例管理類:

public class AfGlobal
{
	public static Map<String, Object>map = new HashMap<>(); //用來存儲實例
	
	/**
	 * 初始化操作
	 */
	public static void init()
	{
		Car car = new Car();
		map.put("car", car);
		
		Plane plane = new Plane();
		map.put("plane", plane);
		
		Train train = new Train();
		map.put("train", train);
	}
	
	/**
	 * 
	 * @param key 
	 * @return 返回對應於key的對象
	 */
	public static Object get(String key)
	{
		return map.get(key);
	}
}

測試類: 

public class Test
{

	public static void main(String[] args)
	{
		//初始化所有全局實例的容器
		AfGlobal.init();
		
		//訪問全局對象
		Car car = (Car)AfGlobal.get("car");
		car.run();
		
		System.out.println("exit");
	}

}

 細節:AfGlobals.map是全局實例,一直存在、不會銷燬,所以此map裏存儲的對象都成了全局實例

3、全局實例框架 

框架,就是對相似的流程進行統一化處理 

每個全局實例的創建、初始化和訪問流程,都是類似的

代碼再升級(2.0)

1、添加af-global.xml配置文件

 

2、由AfGlobal框架自動完成全局實例的創建  loadConfig()

3、當需要訪問時,從AfGlobals取得全局實例的引用 obj = afGlobal.get(name)

將類名字存放到xml文件中,利用對xml的操作來進行處理

全局框架類:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import my.Car;
import my.Plane;
import my.Train;

public class AfGlobal
{
	public static Map<String, Object>map = new HashMap<>(); //用來存儲實例
	
	//靜態代碼快,首次訪問該類時,將運行代碼塊,且只執行一次
	static
	{
		try {
			loadConfig();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 初始化操作
	 * @throws Exception 
	 */
	public static void loadConfig() throws Exception
	{
		InputStream inputStream = AfGlobal.class.getResourceAsStream("/af-global.xml");
		
		if(inputStream == null)
			throw new Exception("找不到指定文件");
		
		//加載xml
		SAXReader reader = new SAXReader();
		Document doc = reader.read(inputStream);
		
		Element root = doc.getRootElement();
		List<Element> serviceList = root.elements("global");
		
		for(Element e : serviceList)
		{
			String name = e.attributeValue("name").trim();
			String clazz = e.attributeValue("class").trim();
			
			//創建實例,存入map
			try 
			{
				Class cls = Class.forName(clazz);
				Object obj = cls.newInstance();
				map.put(name, obj);
			}catch(Exception ex)
			{
				System.out.println("無法加載 : " + clazz + " : " + ex.getMessage());
			}
		}
	}
	
	/**
	 * 
	 * @param key 
	 * @return 返回對應於key的對象
	 */
	public static Object get(String key)
	{
		return map.get(key);
	}
}

 配置文件(放在src目錄下):

<?xml version="1.0" encoding="UTF-8"?>
<config>

	<global name="car" class="my.Car"></global>
	
	<global name="train" class="my.Train"></global>
	
	<global name="plane" class="my.Plane"></global>
	
</config>

 測試類:

import af.global.AfGlobal;

public class Test
{

	public static void main(String[] args)
	{
		
		//訪問全局對象
		Car car = (Car)AfGlobal.get("car");
		car.run();
		
		System.out.println("exit");
	}

}

4、框架的打包 

框架,執行的是統一化的處理流程,所以框架一般是通用的

因此,可以將AfGlobal打包成jar文件 

 

5、框架的優化 (1)

考慮:全局實例在創建之後,可能需要進一步的優化

比如:

使用汽車之前,先給汽車加點油

 

所以:在框架裏應該允許添加一個實例的初始化方法

 1、修改af-global.xml

<global name="car" class="my.Car" init="getReady"></global>

2、修改AfGlobal.loadConfig()

在創建實例之後,緊接着調用它的初始化方法

public class Car
{
	public void run()
	{
		System.out.println("汽車....");
	}
	
	public void getReady()
	{
		System.out.println("加油~~~~~");
	}
}
<?xml version="1.0" encoding="UTF-8"?>
<config>

	<global name="car" class="my.Car" init="getReady"></global>
	
	<global name="train" class="my.Train"></global>
	
	<global name="plane" class="my.Plane"></global>
	
</config>
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import my.Car;
import my.Plane;
import my.Train;

public class AfGlobal
{
	public static Map<String, Object>map = new HashMap<>(); //用來存儲實例
	
	//靜態代碼快,首次訪問該類時,將運行代碼塊,且只執行一次
	static
	{
		try {
			loadConfig();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 初始化操作
	 * @throws Exception 
	 */
	public static void loadConfig() throws Exception
	{
		InputStream inputStream = AfGlobal.class.getResourceAsStream("/af-global.xml");
		
		if(inputStream == null)
			throw new Exception("找不到指定文件");
		
		//加載xml
		SAXReader reader = new SAXReader();
		Document doc = reader.read(inputStream);
		
		Element root = doc.getRootElement();
		List<Element> serviceList = root.elements("global");
		
		for(Element e : serviceList)
		{
			String name = e.attributeValue("name").trim();
			String clazz = e.attributeValue("class").trim();
			String init = e.attributeValue("init");
			
			//創建實例,存入map
			try 
			{
				Class cls = Class.forName(clazz);
				Object obj = cls.newInstance();
				
				if(init != null)
				{
					Method method = cls.getDeclaredMethod(init);
					method.invoke(obj);
				}
				
				map.put(name, obj);
			}catch(Exception ex)
			{
				System.out.println("無法加載 : " + clazz + " : " + ex.getMessage());
			}
		}
	}
	
	/**
	 * 
	 * @param key 
	 * @return 返回對應於key的對象
	 */
	public static Object get(String key)
	{
		return map.get(key);
	}
}

5、框架的優化 (2)

泛型的返回值 ,解決下圖問題

	public static <T>T get(String key)
	{
		return (T)map.get(key);
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章