Java设计模式之工厂模式

Java设计模式之工厂模式

一、设计模式

1、什么是设计模式

设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。

2、应用设计模式有什么好处?

设计模式是优秀的使用案例,使用设计模式可提高代码的重用性,让代码更容易被他人理解,保证代码可靠性。

二、工厂模式

1、工厂模式的概念

工厂模式顾名思义就是创建所需要的对象,可以代替传统的new创建对象方式。
它是一种创建型模式,用于封装和管理对象的创建。
工厂模式包括简单工厂模式、抽象工厂模式和工厂方法模式,抽象工厂模式是工厂方法模式的扩展。抽象工厂模式不常用。

2、工厂模式的意念

定义一个接口来创建对象,让子类来决定哪些类需要被实例化。工厂方法把实例化的工作推迟到子类中实现。

3、工厂模式的应用场景

  • 有一组同类型或类似的对象需要创建
  • 在编码时不能预见需要创建哪种类的实例
  • 系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节。

同一类型的对象需要创建。

4、工厂模式的动机

1)项目中的现状:

在软件系统中经常面临着“对象”的创建工作,由于需要的变化,这个对象可能随之也会发生变化,为此,我们需要提供一种封装机制来隔离出这个易变对象的变化,从而保持系统中其他依赖该对象的对象不随着需求变化而变化。

2)基于项目现状将代码进行如下设计:
  • 尽量松耦合,一个对象的依赖对象的变化与本身无关;
  • 具体产品与客户端剥离,责任分割。

5、工厂模式的应用

包结构目录

在这里插入图片描述

1)传统方式实例对象
IceProjectInterface.java
package com.ice;

/**
 * 冰棒产品接口
 */
public interface IceProjectInterface{
	/**
	 * 打印信息方法
	 */
	public void showInfo();
}
IceCreamImpl.java
package com.ice.impl;

import com.ice.IceProjectInterface;

/**
 * 冰淇淋实现类
 */
public class IceCreamImpl implements IceProjectInterface{
	@Override
	public void showInfo() {
		System.out.println("这里是冰淇淋");
	}
}

IceLollyImpl.java
package com.ice.impl;

import com.ice.IceProjectInterface;
/**
*冰棒实现类
*/
public class IceLollyImpl implements IceProjectInterface{
	@Override
	public void showInfo() {
		System.out.println("这里是冰棒");
	}
}
IceProjectTest.java
package com.ice.test;

import com.ice.IceProjectInterface;
import com.ice.impl.IceCreamImpl;

/**
 * 冰棒产品测试类
 */
public class IceProjectTest{
	public static void main(String[] args){
		//传统方法
		IceProjectInterface iceCream = new IceCreamImpl();
		iceCream.showInfo();
	}
}

在这里插入图片描述

2)简单工厂模式

首先创建一个Factory工厂类

IceProjectFactory.java
package com.ice.factory;

import com.ice.IceProject;
import com.ice.impl.IceCreamImpl;
import com.ice.impl.IceLollyImpl;

/**
 * 冰棒产品工厂类
 */
public class IceProjectFactory{
	/**
	*根据参数创建对象
	*@param name 冰棒产品名称
	*/
	public IceProjectInterface iceProjectByName(String name){
		if("ice-cream".equals(name)){
			return new IceCreamImpl();
		}else if("ice-lolly".equals(name)){
			return new IceLollyImpl();
		}
		return null;
	}
}
IceProjectTest.java
package com.ice.test;

import com.ice.IceProject;
import com.ice.factory.IceProjectFactory;
import com.ice.impl.IceCreamImpl;

/**
 * 冰棒产品测试类
 */
public class IceProjectTest{
	public static void main(String[] args){
		IceProjectInterface iceCream = new IceProjectFactory().iceProjectByName("ice-cream");
		iceCream.showInfo();
	}
}

在这里插入图片描述

3)工厂方法模式

使用这种方式来创建对象时,每增加一个类,我们需要在方法中多添加一个if结构,我们可以使用反射机制,优化代码,并根据类的名称来为我们创建类的实例。

IceProjectFactory.java
   /**
	 * 根据类名创建对象
	 * @param className 类名
	 * @return 返回所需对象
	 */
	public IceProjectInterface iceProjectByClass(String className){
		try {
			IceProjectInterface iceProject = (IceProjectInterface)Class.forName(className).newInstance();
			return iceProject;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
IceProjectTest.java
		IceProjectInterface iceCream = new IceProjectFactory().iceProjectByClass("com.ice.impl.IceCreamImpl");
		iceCream.showInfo();
4)使用映射配置类路径

由于根据类名来查找创建对象,类名过长,我们可以使用简写key的形式,创建映射文件来配置类路径。

type.properties
ice-cream = com.ice.impl.IceCreamImpl
ice-lolly = com.ice.impl.IceLollyImpl
IceProjectFactory.java
   /**
	 * 根据key创建对象
	 * @param className 类名
	 * @return 返回所需对象
	 */
	public IceProjectInterface iceProjectByClassKey(String key){
		try {
			Map<String, String> map = new PropertiesReader().getProperties();
			IceProjectInterface iceProject = (IceProjectInterface)Class.forName(map.get(key)).newInstance();
			return iceProject;
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
IceProjectTest.java
		IceProjectInterface iceCream 
		= new IceProjectFactory().iceProjectByClassKey("ice-cream");
		iceCream.showInfo();

6、抽象工厂模式的应用

创建实现人物项目,以性别和姓名首字母进行分类实现。

包结构目录

在这里插入图片描述

类图

(右键图片新标签页可放大查看)
在这里插入图片描述

代码展示
IBoy.java
package com.people;

/**
 * 男生接口
 */
public interface IBoy {
	/**
	 * 打印信息方法
	 */
	public void showInfo();
}

IGirl.java
package com.people;

/**
 * 女生接口
 */
public interface IGirl {
	/**
	 * 打印信息方法
	 */
	public void showInfo();
}

JackBoy.java
package com.people.impl;

import com.people.IBoy;
public class JackBoy implements IBoy {
	@Override
	public void showInfo() {
		System.out.println("我是Jack");
	}
}

JanGirl.java
package com.people.impl;

import com.people.IGirl;
public class JanGirl implements IGirl {
	@Override
	public void showInfo() {
		System.out.println("我是Jan");
	}
}
NanaGirl.java
package com.people.impl;

import com.people.IGirl;

public class NanaGirl implements IGirl{
	@Override
	public void showInfo() {
		System.out.println("我是Nana");
	}
}

NinkoBoy.java
package com.people.impl;

import com.people.IBoy;

public class NinkoBoy implements IBoy {
	@Override
	public void showInfo() {
		System.out.println("我是Ninko");
	}
}
IPeopleFactory.java
package com.people.factory;

import com.people.IBoy;
import com.people.IGirl;
/**
 * 人物实现接口
 * @author Administrator
 *
 */
public interface IPeopleFactory {
	public IBoy getBoy();
	public IGirl getGirl();
}
JPeopleFactoryImpl.java
package com.people.factory;

import com.people.IBoy;
import com.people.IGirl;
import com.people.impl.JackBoy;
import com.people.impl.JanGirl;
/**
*姓名J开头的人物实现类
*/
public class JPeopleFactoryImpl implements IPeopleFactory {
	@Override
	public IBoy getBoy() {
		return new JackBoy();
	}
	
	@Override
	public IGirl getGirl() {
		return new JanGirl();
	}
}
NPeopleFactoryImpl.java
package com.people.factory;

import com.people.IBoy;
import com.people.IGirl;
import com.people.impl.NanaGirl;
import com.people.impl.NinkoBoy;
/**
*姓名N开头的人物实现类
*/
public class NPeopleFactoryImpl implements IPeopleFactory {
	@Override
	public IBoy getBoy() {
		return new NinkoBoy();
	}

	@Override
	public IGirl getGirl() {
		return new NanaGirl();
	}
}
PeopleTest.java
package com.people.test;

import com.people.IBoy;
import com.people.factory.IPeopleFactory;
import com.people.factory.JPeopleFactoryImpl;

/**
*人物测试类
*/
public class PeopleTest {
	public static void main(String[] args) {
		IPeopleFactory peopleFactory = new JPeopleFactoryImpl();
		IBoy jack = peopleFactory.getBoy();
		jack.showInfo();
	}
}

在这里插入图片描述

工厂方法模式和抽象工厂模式对比
  • 工厂方法模式是一种极端情况的抽象工厂模式,而抽象工厂模式可以看成是工厂模式的推广;
  • 工厂方法模式用来创建一个产品的等级结构,而抽象工厂模式是用来创建多个产品的等级结构;
  • 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。

6、常见应用

1)JDBC

是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组Java语言编写的类和接口组成。

2)Spring BeanFactory

Spring BeanFactory作为Spring基础的IOC容器,是Spring的一个Bean工厂。单从工厂模式的角度思考,它就是用来生产Bean,提供给客户端。

7、工厂模式的好处

  • 工厂模式是为了解耦:可以将对象的创建和使用分离,如果不分离,不但违反了设计模式的开闭原则,需要需要使用另一个子类的话,需要修改源代码 ,把对象的创建和使用的过程分开。
  • 工厂模式可以降低代码重复。
  • 因为工厂管理了对象的创建逻辑,使用者并不需要知道具体的创建过程,只管使用即可,减少了使用者因为创建逻辑导致的错误。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值