01 简单工厂

一:接口回顾
1.Java中接口的概念
  在Java 中接口是一种特殊的抽象类,跟一般的抽象类相比,接口里面的所有方法都是抽象方法,接口里面的属性都是常量。
2.接口是用来干什么的
  接口就是”封装隔离“
  接口用来定义实现类的外观
  接口是系统可插拔性的保证
3.接口和抽象类的选择
  1)优先选用接口
  2)在既要定义子类行为,又要为子类提供公共的功能时应该选择抽象类。

二:面向接口编程
  在Java程序设计里面,非常讲究层的划分和模块的划分。通常按照三层来划分 Java程序,分别是表现层、逻辑层、数据称,它们之间通过接口来通信。
  在每一个层里面,又有很多个小模块,每个小模块对外则是一个整体,所以一个模块对外应该提供接口,其他地方需要使用到这个模块的功能时,可以通过此接口来进行调用。也就是常说的”接口是被其隔离部分的外观“。
  所谓组件:从设计上讲,组件就是能够完成一定功能的封装体。
  从设计的角度看,系统、子系统、模块、组件等说的其实是同一回事,都是完成一定功能的封装体,只不过功能多少而已。

三:简单工厂设计模式
1.不用模式的解决方案
  1)首先定义接口Api,示例代码如下:
<span style="font-size:14px;">/**
 * 某个接口(通用的、抽象的、非具体的)
 */

public interface Api{
	/**
	 * 某个具体的功能方法定义,用test1 来演示一下
	 * 这里的功能很简单,把传人的 s 打印出来即可
	 * @param s 任意想要打印输出字符串
	 */
	
	public void test1(String s);
}</span>
  2)既然有了接口,自然就要有实现,实现 Impl ,示例代码如下
<span style="font-size:14px;">/**
 * 对接口的实现
 */
public class Impl implements Api{
	public void test1(String s ){
		System.out.println("Now In Impl. The input s == "+s);
	}
}</span>
  3)客户端代码示例
<span style="font-size:14px;">/**
 * 客户端:测试使用 Api 接口
 */
public class Client{
	public static void main (String [] args){
		Api api = new Impl();
		api.test1("这是一个测试!");
	}
}</span>

3.使用简单工厂设计模式
  1)Api  定义的示例代码:
<span style="font-size:14px;">/**
 * 接口的定义,该接口可以通过简单工厂来创建
 */
public interface Api{
	/**
	 * 具体功能方法的定义
	 * @param s ,需要的参数
	 */
	public void operation(String s);
}</span>

  2)定义接口。ImplA 的示例代码如下:
<span style="font-size:14px;">/**
 * 接口的具体实现对象 A
 */
public class ImplA implements Api{
	public void operation(String s){
		//实现功能代码
		System.out.println("ImplA s == "+s);
	}
}</span>

  ImplB 的示例代码如下:
<span style="font-size:14px;">/**
 * 接口的具体实现对象 B
 */
public class ImplB implements Api{
	public void operation(String s){
		//实现功能代码
		System.out.println("ImplB s == "+s);
	}
}
</span>

  3)简单工厂的实现,代码如下:
<span style="font-size:14px;">/**
 * 工厂类,用来创建 Api 的
 */
public class Factory{
	/**
	 * 防止客户端无谓地创造简单的工厂实例,把构造方法私有化
	 */
	private Factory(){
		
	}
	
	/**
	 * 简单工厂的方法内部主要实现的功能是——选择合适的实现类
	 * 选择的条件和参数的来源:
	 * 1.来源于客户端,由Client来传人参数
	 * 2.来源于配置文件,从配置文件获取用于判断的值
	 * 3.来源于程序运行期的某个值,比如从缓存中获取某个运行期间的值,或者数据库中的值
	 */
	public static Api getApi(int type){
		Api api = null;
		/**
		 * Api 接口的实现类可以有多个,可以更具需要来选择使用那种实现方式
		 */
		if(type == 1){
			api = new ImplA();
		}
		else if(type == 2){
			api = new ImplB();
		}
	}
}
</span>

  4)客户端代码如下:
/**
 * 客户端代码,测试使用Api接口
 */
public class Client {
	public static void main(String [] args){
		//注意这里传递的参数
		Api api = Factory.getApi(2);
		api.test1("这只是一个测试!");
	}
}

4.可配置的简单工厂
  1)环境和问题
   现在希望新增加了实现类过后不修改工厂类,怎么办?
   一个解决的方法就是使用配置文件,当有了新的实现类后,只要在配置文件里面配置上性的实现类即可。在简单工厂的方法里面可以使用反射。

  2)使用可配置的简单工厂
  a.配置文件使用最简单的 properties 文件,实际开发中多是xml配置。
   定义一个名为“”的配置文件,放置到Factory 同一个包下面,内容如下:
ImplClass = cn.javass.dp.simplefactory.example5.Impl
   如果添加了实现类,修改这里的配置文件即可。

  b.此时的工厂类实现如下:
/**
 * 工厂类,用来创建Api 对象
 */
public class Factory{
	/**
	 * 具体创建 Api 的方法,根据配置文件的参数来创建接口
	 * @return 创建好的 Api 对象
	 */
	public static Api getApi(){
		//直接读取配置文件来获取需要创建实例的类
		//至于如何读取 Properties ,还有如何反射就不解释了
		Properties p = new Properties();
		ImputStream in = null;
		try{
			in = Factory.class.getResourceAsStream("FactoryTest.properties");
			p.load(in);
		}catch(IOException e){
			System.out.println("装载工厂配置文件出错了,具体的堆栈信息如下:");
			e.printStackTrace();
		}finally{
			try{
				in.close();
			}catch(IOException e){
				e.printStackTrace();
			}
		}
		
		//用反射去创建,那些列外处理等完善工作这里就不做了
		Api api = null;
		try{
			api = (Api)Class.forName(p.getProperty("ImplClass").newInstance());
		}catch(InstantiationException e){
			e.printStackTrace();
		}catch(IllegalAccessException e ){
			e.printStackTrace();
		}catch(ClassNotFoundException e){
			e.printStackTrace();
		}
		
		return api;
	}
}

c.客户端的代码:
public class Client{
	public static void main(String[] args){
		Api api = Factory.getApi();
		api.test1("这是一个测试!");
	}
}

四:总结简单工厂
1.简单工厂的功能
  一定要注意,虽然示例代码是利用简单工厂来创建接口,但是也可以用简单工厂来创建抽象类或普通类的实例。
2.静态工厂
  简单工厂的方法通常是静态的,所以它被称为静态工厂。通常不需要创建简单工厂的类实例,所以如果要防止客户端无谓地创造简单工厂实例,还可以把简单工厂的构造方法私有化。
3.万能工厂
  一个简单工厂可以包含很多用来构造东西的方法,这些方法可以创建不同的接口,抽象类,或是类实例。
  简单工厂可以有多个构造接口,抽象类,实例类对象的方法。
4.简单工厂创建对象的范围
  通常不要太大,建议控制在一个独立的组件级别或者一个模块级别,也就是一个组件或模块简单工厂,否则这个工厂会职责不明。
5.简单工厂的命名建议
  1)类名称建议为“模块名称+Factory”
  2)方法通常为“get+接口名称”或者“create+接口名称”

五:思考简单工厂
1.简单工厂的本质
  简答工厂的本质是:选择实现
  实现工厂的难点就在于“如何选择”的实现,前面讲到了几种传递参数的方法都是静态的参数,还可以实现成为动态的参数。比如在运行期间,由工厂去读取摸个内存的值,或者是读取数据库中的值,然后在根据具体的值来实现。
2.合适选用简单工厂
  1)如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体。
  2)如果想要把对外创建对象的指责集中管理和控制。



















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值