第二十三部分_Spring入門之簡單工廠模式

意圖:java

簡單工廠模式是類的建立模式,又叫作靜態工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠對象決定建立出哪種產品類的實例。一般它根據自變量的不一樣返回不一樣的類的實例。spring

適用性:app

簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該建立出哪個產品類的實例。ide

簡單工廠模式的構成:工具

  • 工廠類(Creator)角色:擔任這個角色的是簡單工廠模式的核心,含有與應用緊密相關的商業邏輯。工廠類在客戶端的直接調用下建立產品對象,它每每由一個具體類實現。
  • 抽象產品(Product)角色:擔任這個角色的類是簡單工廠模式所建立的對象的父類,或它們共同擁有的接口。抽象產品角色能夠用一個接口或者抽象類實現。
  • 具體產品角色(Concrete Product):簡單工廠模式所建立的任何對象都是這個角色的實例,具體產品角色由一個具體類實現。

下面創建一個Java Project來實現簡單工廠模式:ui

新建simplefactory項目,src下創建com.test.simplefactory包,首先是抽象產品角色,好比人,定義一個接口Person.java:this

package com.test.simplefactory;

public interface Person
{
	public String sayHello(String name);
	
	public String sayGoodbye(String name);
}

下面定義中國人和美國人這樣兩個具體產品角色:編碼

定義一個實現了Person接口的Chinese類:xml

package com.test.simplefactory;

public class Chinese implements Person
{

	@Override
	public String sayGoodbye(String name)
	{
		return "再見, " + name;
	}

	@Override
	public String sayHello(String name)
	{
		return "你好, " + name;
	}

}

而後是實現了Person接口的American類:對象

package com.test.simplefactory;

public class American implements Person
{

	@Override
	public String sayGoodbye(String name)
	{
		return "good bye, " + name;
	}

	@Override
	public String sayHello(String name)
	{
		return "hello, " + name;
	}

}

按照之前的方式,在不使用工廠類的狀況下,咱們編寫客戶端Client類以下:

package com.test.simplefactory;

public class Client
{
	public static void main(String[] args)
	{
		Person chinese = new Chinese();
		
		System.out.println(chinese.sayHello("張三"));
		System.out.println(chinese.sayGoodbye("張三"));
		
		Person american = new American();
		
		System.out.println(american.sayHello("Tom"));
		System.out.println(american.sayGoodbye("Tom"));
	}
}

運行Client.java,輸出以下:

你好, 張三
再見, 張三
hello, Tom
good bye, Tom

下面,咱們來分析一下這個程序有哪些不足的地方:客戶端與具體實現類強耦合在一塊兒,具體實現類增長、刪除、修改了,客戶端類都要隨之發生變化。下面咱們看看如何用工廠模式完成一樣的功能。

新建一個PersonFactory類:

package com.test.simplefactory;

public class PersonFactory
{
	public Person getPerson(String name)
	{
		if("american".equals(name))
		{
			return new American();
		}
		else if("chinese".equals(name))
		{
			return new Chinese();
		}
		else
		{
			return null;
		}
	}
		
		
}

如此以來,客戶端Client就能夠這樣寫了:

package com.test.simplefactory;

public class Client
{
	public static void main(String[] args)
	{
		PersonFactory factory = new PersonFactory();
		
		Person chinese = factory.getPerson("chinese");
		
		System.out.println(chinese.sayHello("張三"));
		System.out.println(chinese.sayGoodbye("張三"));
		
		
		Person american = new American();
		
		System.out.println(american.sayHello("Tom"));
		System.out.println(american.sayGoodbye("Tom"));
		
	}
}

這樣作的話,咱們的客戶端已經和具體的實現類沒有強耦合這樣的關係了,徹底被工廠所掩蓋了。這就是Spring IoC(Inverse of Control,控制反轉)/DI(Dependency Injection,依賴注入)的基礎。

接下來,咱們用Spring重現這個過程:新建一個Java Project:命名爲Spring1。

MyEclipse一樣提供了對Spring的支持,src->MyEclipse->Add Spring Capabilities,選擇Spring version版本號爲Spring2.5,點擊Next,去掉Enable AOP Builder前的勾勾,點擊Finish。此時src包下便多了一個Spring相關的配置文件:applicationContext.xml。

在src下面新建包:com.test,將simplefactory下的American、Chinese、Person這三個類拷貝到其下。接下來咱們利用Spring做爲工廠,實現相應的功能。

在applicationContext.xml中配置以下信息:

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="chinese" class="com.test.Chinese"></bean>
	<bean id="american" class="com.test.American"></bean>

</beans>

而後新建一個Client類:

package com.test;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Client
{
	public static void main(String[] args)
	{
		ClassPathResource cpr = new ClassPathResource("applicationContext.xml");
		
		XmlBeanFactory factory = new XmlBeanFactory(cpr);
	
		Person chinese = (Person)factory.getBean("chinese");
		
		System.out.println(chinese.sayHello("張三"));
		System.out.println(chinese.sayGoodbye("張三"));
	}
}

運行能夠獲得和以前simplefactory項目相同的結果,這樣咱們就經過Spring實現了控制反轉(IoC/DI)。

如今對Spring咱們能夠說有了一些初步的認識,接下來咱們看一些更復雜的例子,看看Spring爲咱們提供了哪些強大的功能。

如前步驟,新建Java項目Spring2,新建com.test包。下面咱們常識使用Spring提供的依賴注入:對象依賴的其餘屬性由Spring自動幫咱們生成好。

在該包下面創建接口類Person:

package com.test;

public interface Person
{
	public void work();
}

人工做須要藉助工具來完成,所以咱們寫一個接口類Tool:

package com.test;

public interface Tool
{
	public void realWork();
}

下面是工具的兩個實現類ConcreteToolA和ConcreteToolB:

package com.test;

public class ConcreteToolA implements Tool
{
	@Override
	public void realWork()
	{
		System.out.println("realwork from ConcreteToolA");
	}
	
}

----------------------------------------------------------------------------------------------
package com.test;

public class ConcreteToolB implements Tool
{
	@Override
	public void realWork()
	{
		System.out.println("realwork from ConcreteToolB");
	}
	
}

而後是實現了Person類的Chinese類:

package com.test;

public class Chinese implements Person
{
	private Tool tool;
	
	public void setTool(Tool tool)
	{
		this.tool = tool;
	}
	
	public Tool getTool()
	{
		return tool;
	}
	
	@Override
	public void work()
	{
		tool.realWork();
	}
}

若是不借助Spring的話Client編碼以下:

package com.test;

public class Client
{
	public static void main(String[] args)
	{
		Chinese chinese = new Chinese();
		
		Tool tool = new ConcreteToolA(); // Tool tool = new ConcreteToolB();
		
		chinese.setTool(tool);
		
		chinese.work();
	}
}

客戶端與人和工具耦合,給咱們帶來了許多不便之處。接下來咱們看看如何用Spring把這些耦合通通給去除掉。

在applicationContext.xml中配置以下:

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="toolA" class="com.test.ConcreteToolA"></bean>
	<bean id="toolB" class="com.test.ConcreteToolB"></bean>

	<bean id="chinese" class="com.test.Chinese">
		<property name="tool" ref="toolA"></property>
	</bean>
</beans>

客戶端Client:

package com.test;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class Client
{
	public static void main(String[] args)
	{
		ClassPathResource cpr = new ClassPathResource("applicationContext.xml");
		
		XmlBeanFactory factory = new XmlBeanFactory(cpr);
		
		Person p = (Person)factory.getBean("chinese");
				
		p.work();
	}
}

照樣可以獲得輸出:real work from ConcreteToolA。

MyEclipse操做補充:當配置文件很大的時候,如何快速瀏覽bean之間的依賴關係:Window->Show View->Spring Explorer。在列出的Spring項目中的applicationContext.xml上點擊右鍵->Open Graph。便可以圖形化的形式瀏覽各個bean之間的關係,好比Spring2項目下的bean之間的依賴關係:

補充:對於Spring2項目來講,就像Struts的Action同樣,對於每個屬性咱們要爲其提供對應的get和set方法,對於Spring來講,若是一個類裏面有屬性,那麼咱們至少要爲這個屬性提供一個set方法,讓Spring根據配置文件中指定的依賴關係經過調用set方法的方式設置到對應的成員變量上。

相關文章
相關標籤/搜索