Java设计模式中的简单工厂模式解析

 更新时间:2023年11月27日 10:37:19   作者:一码评川  
这篇文章主要介绍了Java设计模式中的简单工厂模式解析,简单工厂模式提供一个创建对象实例的功能,而无须关心其具体实现,被创建实例的类型可以是接口、抽象类,也可以是具体的类,需要的朋友可以参考下

一、定义

定义: 提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。

PS: 我们都知道JAVA思想一直推崇“面向接口编程”。而接口的思想就是“封装隔离”,即外部调用只能通过接口进行调用,外部调用并不知道内部具体实现,也就是说外部调用和内部实现是被接口隔离开的。那么只要接口不变,内部实现的变化就不会影响到外部应用,使得系统更加灵活,增加系统的扩展性和可维护性,这也就是所谓的“接口是系统可拔插的保证”。

二、案例

假设有一个接口叫Api,然后有一个实现类Impl实现了它,如何在客户端使用这个接口? So Easy !我们可以很快画出这个案例的类图并写出代码。

在这里插入图片描述

/**
 * @ClassName Api
 * @Description: 定义一个接口
 * @author Jerry
 * @date 2016年3月26日 下午11:27:32
 */
public interface Api {
	/** 
	* @Description: 简单实现,传入字符串打印 
	* @param @param str  
	*/
	public void test(String str);
}
/**
 * @ClassName Impl
 * @Description: 实现Api接口
 * @author Jerry
 * @date 2016年3月27日 上午10:12:27
 */
public class Impl implements Api {
	
	@Override
	public void test(String str) {
		System.out.println(str);
	}
}
/**
 * @ClassName Client
 * @Description: 外部调用
 * @author Jerry
 * @date 2016年3月27日 上午10:13:35
 */
public class Client {
 
	public static void main(String[] args) {
		Api api = new Impl();
		api.test("最爱你的人是我,你怎么舍得我难过");
	}
 
}

三、使用模式的情况

如果我们仔细想想就会发现,这样的设计违背了接口的设计原则。因为客户端必须知道哪些具体实例实现了接口,并没有实现“封装隔离”。其实这里只是用到了接口的多态功能。

在这里插入图片描述

/**
 * @ClassName Factory
 * @Description: 其余代码和之前没有变化,只增加这样工厂类即可
 * @author Jerry
 * @date 2016年3月27日 上午10:23:30
 */
public class Factory {
	
	/** 
	* @Description: 通常把Factory当成一个工具类,不需要创建类实例,所以直接使用静态方法 
	* @param 当然可以添加参数,使得客户端可以选择自己想要初始化的实例,但不推荐,后面会解释原因  
	* @return Api  返回一个具体实现
	* @throws 
	*/
	public static Api createApi() {
		return new Impl();
	}
}
/**
 * @ClassName Client
 * @Description: 外部调用
 * @author Jerry
 * @date 2016年3月27日 上午10:13:35
 */
public class Client {
 
	public static void main(String[] args) {
//		Api api = new Impl();
		Api api = Factory.createApi();	//无须在客户端直接new具体实现
		api.test("最爱你的人是我,你怎么舍得我难过");
	}
 
}

一个简单工厂理论上可以创造任何东西,所以又称为“万能工厂”。简单工厂的本质在于“选择合适的实现类”,既然要选择,那么肯定需要用户去指定参数,通常有以下3种:

  1. 来源于客户端,指定参数。例如我们可以在创建实例的方法中加入参数,这样客户端可以传入具体参数来获得自己想要的实例。但是这样会带来一个问题,客户端必须知道每个参数的含义功能,使得向用户暴露了一定的内部实现细节。通常我们使用配置文件的写法。
  2. 来源于配置文件,从配置文件获取用于判断的值,下文会具体介绍。
  3. 来源于程序运行期的某个值,比如内存中的某个变量值,此方法属于动态实现。
    • 使用配置文件进行优化 我们使用properties文件,放在Factory同一个包下。
    • ImplClass=simpleFactory.Impl 然后修改Factory类,其余不变:
/**
 * @ClassName Factory
 * @Description: 其余代码和之前没有变化,只增加这样工厂类即可
 * @author Jerry
 * @date 2016年3月27日 上午10:23:30
 */
public class Factory {
	
	public static Api createApi() {
		Properties properties = new Properties();
		InputStream in = null;
		try {
			in = Factory.class.getResourceAsStream("factory.properties");
			properties.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		Api api = null;
		try {
			//使用反射创建实例
			api = (Api) Class.forName(properties.getProperty("ImplClass")).newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return api;
	}
	
	/** 
	* @Description: 通常把Factory当成一个工具类,不需要创建类实例,所以直接使用静态方法 
	* @param 当然可以添加参数,使得客户端可以选择自己想要初始化的实例,但不推荐,后面会解释原因  
	* @return Api  返回一个具体实现
	* @throws 
	*/
	@Deprecated
	public static Api createApi1() {
		return new Impl();
	}
	
}

使用配置文件的写法好处在于,可以更加便捷的更改具体实现类,无须修改代码,使得耦合性降低。

四、总结

何时选用简单工厂

如果想要完全封装隔离具体实现,让外部只能通过接口来操作封装体。想要把对外创建对象的职责集中管理和控制,因为简单工厂也称万能工厂,可以创建很多的,不相关的对象。

到此这篇关于Java设计模式中的简单工厂模式解析的文章就介绍到这了,更多相关java简单工厂模式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈java日志格式化

    浅谈java日志格式化

    不管我们使用何种语言开发,一旦程序发生异常,日志是一个很重要的数据。但是并不是意味着打印的日志越多越好,我们需要的是有用的日志。下面小编来和大家一起学习以下知识
    2019-05-05
  • java实现ModbusCRC16校验的示例代码

    java实现ModbusCRC16校验的示例代码

    本文介绍了使用Java实现ModbusCRC16校验,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-11-11
  • 详解Java实现设计模式之责任链模式

    详解Java实现设计模式之责任链模式

    责任链模式是一种行为设计模式,允许你将请求沿着处理链发送,然后处理者都可对其进行处理,完成后可以再将其传递给下一个处理者。下面将会举例说明什么是责任链模式,责任链模式该如何使用
    2021-06-06
  • Java Collections.sort()排序代码案例

    Java Collections.sort()排序代码案例

    这篇文章主要介绍了Java Collections.sort()排序代码案例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • Java 如何从list中删除符合条件的数据

    Java 如何从list中删除符合条件的数据

    这篇文章主要介绍了Java 如何从list中删除符合条件的数据,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • java字符流缓冲区详解

    java字符流缓冲区详解

    这篇文章主要为大家详细介绍了java字符流缓冲区的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • 三道java新手入门面试题,通往自由的道路--多线程

    三道java新手入门面试题,通往自由的道路--多线程

    这篇文章主要为大家分享了最有价值的3道多线程面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,对hashCode方法的设计、垃圾收集的堆和代进行剖析,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • logback-spring.xml的内容格式详解

    logback-spring.xml的内容格式详解

    这篇文章主要介绍了logback-spring.xml的内容格式详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的的朋友参考下吧
    2023-11-11
  • 解决springboot启动报错bean找不到的问题

    解决springboot启动报错bean找不到的问题

    这篇文章主要介绍了解决springboot启动报错bean找不到原因,本文给大家分享完美解决方案,通过图文相结合给大家介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • SpringMVC @RequestBody出现400 Bad Request的解决

    SpringMVC @RequestBody出现400 Bad Request的解决

    这篇文章主要介绍了SpringMVC @RequestBody出现400 Bad Request的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04

最新评论