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