【设计模式系列】--简单工厂模式

简介: 简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。简单来说,通过专门定义一个类来辅助创建其他类的实例,被创建的实例通常都具有共同的父类,今天这篇博文,小编主要简单的介绍一下简单工程模式,通过简单的demo一步一步进行讲解,希望对有需要的小伙伴有帮助,还请小伙伴们多多指教。首先,我们来看一下简单工厂的uml图,如下所示:

接着,小编结合一个简单的demo,来更好的帮助小伙伴们理解简单工厂模式,首先我们新建一个java项目,取名为SimpleFactory,新建三个类Apple、Banana、MainClass,代码分别如下所示:

Apple类的代码:

public class Apple {
	/**
	 * 采集
	 */
	public void get(){
		System.out.println("采集苹果");
	}

}
Banana类的代码:

public class Banana {
	/**
	 * 采集
	 */
	public void get(){
		System.out.println("采集香蕉");
	}

}
编写MainClass里面的代码,如下所示:
public class MainClass {

	public static void main(String[] args){
		//实例化一个Apple
		Apple apple = new Apple();
		//实例化一个Banana
		Banana banana = new Banana();
		
		apple.get();
		banana.get();
		
		
	}
}
运行,效果如下所示:


我们的代码是否还可以进行优化呢?通过Apple类和Banana类我们可以发现,她们都具有get方法,更重要的是,她们都属于水果,所以这个时候,我们可以抽象出来一个接口,so,我们创建一个接口,代码如下所示:

public interface Fruit {
	/**
	 * 采集
	 */
	public void get();
	
}
Apple类和Banana类分别实现接口Fruit,注释掉之前MainClass里面的代码,重新编写,这样,我们这里就用到了多态,代码如下所示:

public class MainClass {

	public static void main(String[] args){
//		//实例化一个Apple
//		Apple apple = new Apple();
//		//实例化一个Banana
//		Banana banana = new Banana();
//		
//		apple.get();
//		banana.get();
		
		//实例化一个Aplle和Banana,用到了多态
		Fruit apple = new Apple();
		Fruit banana = new Banana();
		apple.get();
		banana.get();
		
		
	}
}
运行,效果如下所示:


接着,我们回过头来看一下简单工厂模式的概念,通过专门定义一个类来辅助辅助创建其她类的实例,被创建的实例通常都具有共同的父类,从上面的demo中,我们可以看出来,Apple类和Banana类具有一个共同的父类,那就是Fruit,这个时候,我们需要专门定义一个类来辅助创建其她类的实例,接着,我们再来进行优化,创建一个类FruitFactory,代码如下所示:

public class FruitFactory {
	/**
	 * 获得Apple类的实例
	 */
	
	public static Fruit getApple(){
		return new Apple();
	}
	
	/**
	 * 获得Banana类的实例
	 */
	public static Fruit getBanana(){
		return new Banana();
	}
}
编写main里面的代码,如下所示:

public class MainClass {

	public static void main(String[] args){
//		//实例化一个Apple
//		Apple apple = new Apple();
//		//实例化一个Banana
//		Banana banana = new Banana();
//		
//		apple.get();
//		banana.get();
		
//		//实例化一个Aplle和Banana,用到了多态
//		Fruit apple = new Apple();
//		Fruit banana = new Banana();
//		apple.get();
//		banana.get();

		//实例化一个Apple
		Fruit apple = FruitFactory.getApple();
		Fruit banana = FruitFactory.getBanana();
		apple.get();
		banana.get();
		
	}
}
运行一下,效果如下所示:


这样,我们实现了专门定义一个类来辅助创建其她类的实例,那我们还能不能进一步进行优化呢?答案是肯定的,我们可以把这些方法写成一个静态的方法,我们直接可以通过类名类进行引用,不需要创建工程类的实例,我们来看一下模式中包含的角色及其职责。

a、工厂角色---Creator

简单工厂模式的核心,她负责实现创建所有实例的内部逻辑,工厂类可以被外界直接调用,创建所需要的产品对象。

b、抽象角色--Product

简单工厂模式所创建的所有对象的父类,她负责描述所有实例所共有的公共接口。

c、具体产品角色--Concrete Product

简单工厂模式所创建的具体实例对象

那么,工厂还能否进行进一步的优化呢?yes,我们发现工厂里面分别单独getApple和getBanana,我们是否能写一个公共的getFruit的方法呢?进行优化,编写FruitFactory里面的代码,如下所示:

public class FruitFactory {
//	/**
//	 * 获得Apple类的实例
//	 */
//	
//	public static Fruit getApple(){
//		return new Apple();
//	}
//	
//	/**
//	 * 获得Banana类的实例
//	 */
//	public static Fruit getBanana(){
//		return new Banana();
//	}
	/**
	 * get方法,获得所有产品对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 */
	public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException {
		if(type.equalsIgnoreCase("apple")) {
			return Apple.class.newInstance();
		}else if(type.equalsIgnoreCase("banana")){
			return Banana.class.newInstance();
		}else{
			System.out.println("找不到相关实例化类");
			return null;
			
		}
	}
	
}
编写MainClass的代码,如下所示:

public class MainClass {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException{
//		//实例化一个Apple
//		Apple apple = new Apple();
//		//实例化一个Banana
//		Banana banana = new Banana();
//		
//		apple.get();
//		banana.get();
		
//		//实例化一个Aplle和Banana,用到了多态
//		Fruit apple = new Apple();
//		Fruit banana = new Banana();
//		apple.get();
//		banana.get();

//		//实例化一个Apple
//		Fruit apple = FruitFactory.getApple();
//		Fruit banana = FruitFactory.getBanana();
//		apple.get();
//		banana.get();
		
		Fruit apple = FruitFactory.getFruit("apple");
		Fruit banana = FruitFactory.getFruit("banana");
		apple.get();
		banana.get();
		
		
	}
}
运行,效果如下所示:


我们知道,每一种模式都是经过不断的改进,最后达到业内都能接受的一种规范,so,我们还可以进行优化,编写FruitFactory的内容,如下所示:

public class FruitFactory {
//	/**
//	 * 获得Apple类的实例
//	 */
//	
//	public static Fruit getApple(){
//		return new Apple();
//	}
//	
//	/**
//	 * 获得Banana类的实例
//	 */
//	public static Fruit getBanana(){
//		return new Banana();
//	}
	/**
	 * get方法,获得所有产品对象
	 * @throws IllegalAccessException 
	 * @throws InstantiationException 
	 * @throws ClassNotFoundException 
	 */
	public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
//		if(type.equalsIgnoreCase("apple")) {
//			return Apple.class.newInstance();
//		}else if(type.equalsIgnoreCase("banana")){
//			return Banana.class.newInstance();
//		}else{
//			System.out.println("找不到相关实例化类");
//			return null;
//			
//		}
		Class fruit = Class.forName(type);
		return (Fruit) fruit.newInstance();
	}
	
}
编写MainClass的代码,如下所示:

public class MainClass {

	public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
//		//实例化一个Apple
//		Apple apple = new Apple();
//		//实例化一个Banana
//		Banana banana = new Banana();
//		
//		apple.get();
//		banana.get();
		
//		//实例化一个Aplle和Banana,用到了多态
//		Fruit apple = new Apple();
//		Fruit banana = new Banana();
//		apple.get();
//		banana.get();

//		//实例化一个Apple
//		Fruit apple = FruitFactory.getApple();
//		Fruit banana = FruitFactory.getBanana();
//		apple.get();
//		banana.get();
		
		Fruit apple = FruitFactory.getFruit("Apple");
		Fruit banana = FruitFactory.getFruit("Banana");
		apple.get();
		banana.get();
		
		
	}
}
运行一下,效果如下所示:


接着,我们来看一下简单工厂模式的优缺点:

在这个模式中,工厂类是整个模式的关键所在,她包含的必要的判断楼哦机,能够根据外界给定的信息,决定究竟应该创建哪个具体类的对象,用户在使用时可以直接根据工厂类去创建所需的实例,而无需了解这些对象是如何创建以及如何组织的,有利于整个廉体系结构的优化。

不难发现,简单工厂模式的确定也正体现在其工厂类上,由于工厂类几种了所有实例的创建逻辑,所以“高内聚”方面做的并不好,另外,当系统中的具体产品类不断增多时,可能会出现要求工厂类也要做相应的修改,扩展性不是很好,如下代码:

public static Fruit getFruit(String type) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
		if(type.equalsIgnoreCase("apple")) {
			return Apple.class.newInstance();
		}else if(type.equalsIgnoreCase("banana")){
			return Banana.class.newInstance();
		}else{
			System.out.println("找不到相关实例化类");
			return null;
			
		}
		Class fruit = Class.forName(type);
		return (Fruit) fruit.newInstance();
	}

如果这个时候再添加一个橙子,so我们需要添加一个else if来进行判断,下面那种方法会解决我们的问题,但是也不能从根本上解决问题,我们调用的时候会比较麻烦,因为这个类你必须知道,对于客户而言,是比较麻烦的,一般我们会受用第二种,不用考虑大小写,虽然第三种扩展性好,但是适用性较差。

小编寄语:该博文,小编主要简单的介绍了简单工厂模式,通过一个简单的demo进行讲解,简单工厂模式是属于创建型模式,又叫做静态工厂方法模式,但不属于二十三中GOF设计模式之一,简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例,简单工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一种特殊实现,想起那句话,编程是一门技术,更是一门艺术,在编写代码的过程中,要牢记可复用、易维护、好扩展,这样,自己才能有所提高,才是真正的软件工程师。

目录
相关文章
|
10天前
|
设计模式 SQL 算法
设计模式了解哪些,模版模式
设计模式了解哪些,模版模式
19 0
|
30天前
|
设计模式 Java uml
C++设计模式之 依赖注入模式探索
C++设计模式之 依赖注入模式探索
37 0
|
3月前
|
设计模式 存储 算法
Java 设计模式最佳实践:三、行为模式
Java 设计模式最佳实践:三、行为模式
|
3月前
|
设计模式 Go 开发工具
Golang设计模式——12中介模式
Golang设计模式——12中介模式
25 0
|
2月前
|
设计模式 前端开发 JavaScript
观察者模式 vs 发布-订阅模式:两种设计模式的对决!
欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚开始学习前端的读者们打造的。无论你是初学者还是有一些基础的开发者,我们都会在这里为你提供一个系统而又亲切的学习平台。我们以问答形式更新,为大家呈现精选的前端知识点和最佳实践。通过深入浅出的解释概念,并提供实际案例和练习,让你逐步建立起一个扎实的基础。无论是HTML、CSS、JavaScript还是最新的前端框架和工具,我们都将为你提供丰富的内容和实用技巧,帮助你更好地理解并运用前端开发中的各种技术。
|
7天前
|
设计模式 Java 数据库
小谈设计模式(2)—简单工厂模式
小谈设计模式(2)—简单工厂模式
|
7天前
|
设计模式 Java
小谈设计模式(9)—工厂方法模式
小谈设计模式(9)—工厂方法模式
|
1月前
|
设计模式 编译器
解析器模式--设计模式
解析器模式--设计模式
17 0
|
1月前
|
设计模式 算法
构建器模式--设计模式
构建器模式--设计模式
17 0
|
1月前
|
设计模式
【设计模式】中介模式
【设计模式】中介模式