工厂模式的概念:
实例化对象,用工厂方法代替new操作
工厂模式包括工厂方法模式和抽象工厂模式
抽象工厂模式是工厂方法模式的扩展
工厂模式的意图:
定义一个接口来创建对象,但是让子类来决定哪些类需要被实例化
工厂方法把实例化的工作推迟到子类中去实现。
工厂模式的应用场景:
有一组类似的对象需要创建
在编码时不能预见需要创建哪种类的实例
系统需要考虑扩展性,不应依赖于产品类实例如何被创建、组合和表达的细节
工厂模式的动机:
项目中的现状:
在软件系统中经常面临着“对象”的创建工作,由于需求的变化,这个对象可能随之也会发生变化,但它却拥有比较稳定的接口。
为此,我们需要提供一种封装机制来隔离出这个易变对象的变化,从而保持系统中其他依赖该对象不随着需求变化而变化。
基于项目现状将代码进行如下设计:
1、尽量松耦合,一个对象的依赖对象的变化与本身无关
2、具体产品与客户端剥离,责任分割
工厂模式的应用:
JDBC:是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它有一组Java语言编写的类和接口组成。
Spring beanfactory
BeanFactory,作为Spring基础的IoC容器,是Spring的一个Bean工厂。如果单从工厂模式的角度思考,它就是用来“生产Bean”,然后提供给客户端。
Bean的实例化过程如下:
1、调用Bean的默认构造方法,或指定的构造方法,生产Bean实例(暂称为instance1)
2、如果Bean的配置文件中注入了Bean属性值,则在instance1基础上进行属性注入形成instance2,这种注入是覆盖性的
3、如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法,来改变或操作instance2,得到instance3
4、如果Bean的配置文件中指定了init-method="init"属性,则会调用指定的初始化方法,则在instance3的基础上调用初始化方法init(),将对象最终初始化为instance4;当然,这个初始化的名字是任意的。
package com.practice;
/*
* 发型工厂
*/
public class HairFactory {
/*
* 根据类型创建对象
*/
public Hair getHair(String key){
if("left".equals(key)){
return new LeftHair();
}else if("right".equals(key)){
return new RightHair();
}
return null;
}
/*
* 根据类的名称来生产对象
*/
public Hair getHairByClass(String className){
try {
Hair hair = (Hair) Class.forName(className).newInstance();
return hair;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.practice;
/*
* 发型接口
*/
public interface Hair {
//实现了发型
public void draw();
}
package com.practice;
/*
* 左偏分发型
*/
public class LeftHair implements Hair {
/*
* 画了一个左偏分发型(non-Javadoc)
* @see com.practice.Hair#draw()
*/
@Override
public void draw() {
System.out.println("-------左偏分发型-------");
}
}
package com.practice;
/*
* 右偏分发型
*/
public class RightHair implements Hair {
@Override
public void draw() {
System.out.println("-------右偏分发型-------");
}
}
package com.practice;
/*
* 模拟客户端的实现
*/
public class SunnyTest {
public static void main(String[] args) {
// Hair leftHair = new LeftHair();
// leftHair.draw();
HairFactory factory = new HairFactory();
// Hair leftHair = factory.getHair("left");
// leftHair.draw();
Hair left = factory.getHairByClass("com.practice.LeftHair");
left.draw();
}
}