第二十三部分_Spring入门之简单工厂模式

意图:

简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。通常它根据自变量的不同返回不同的类的实例。

适用性:

简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建出哪一个产品类的实例。

简单工厂模式的构成:

  • 工厂类(Creator)角色:担任这个角色的是简单工厂模式的核心,含有与应用紧密相关的商业逻辑。工厂类在客户端的直接调用下创建产品对象,它往往由一个具体类实现。
  • 抽象产品(Product)角色:担任这个角色的类是简单工厂模式所创建的对象的父类,或它们共同拥有的接口。抽象产品角色可以用一个接口或者抽象类实现。
  • 具体产品角色(Concrete Product):简单工厂模式所创建的任何对象都是这个角色的实例,具体产品角色由一个具体类实现。

下面建立一个Java Project来实现简单工厂模式:

新建simplefactory项目,src下建立com.test.simplefactory包,首先是抽象产品角色,比如人,定义一个接口Person.java:

package com.test.simplefactory;

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

下面定义中国人和美国人这样两个具体产品角色:

定义一个实现了Person接口的Chinese类:

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方法的方式设置到对应的成员变量上。

转载于:https://www.cnblogs.com/Code-Rush/p/4864954.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值