工厂模式
前言
Java是一门面向对象编程语言,开发过程中经常需要实例化很多的对象。使用new来创建对象,经常会增加代码耦合度。为了实现解耦经常使用的一种方式是利用工厂模式封装创建对象的代码。
走进工厂模式
工厂模式一般分为三类简单工厂、工厂方法模式、抽象工厂模式。
下面我们通过例子,了解三种不同的工厂模式。
假设现在有一个果汁的系统,果汁系统根据果汁名称返回相应的果汁类型,代码如下所示:
package cn.lzz.hf.forth;
public class SimpleJuiceStore {
/**
* 生产果汁方法
* @param name
* @return
*/
public Juice orderJuice(String name){
Juice juice=null;
switch(name){
case "mango":
juice=new MangoJuice();
break;
case "orange":
juice=new OrangeJuice();
break;
case "watermelon":
juice=new WatermelonJuice();
break;
default:
return null;
}
juice.prepare();
juice.make();
juice.box();
return juice;
}
}
package cn.lzz.hf.forth;
public abstract class Juice {
/**
* 准备
*/
public abstract void prepare();
/**
* 制作
*/
public abstract void make();
/**
* 打包
*/
public abstract void box();
}
package cn.lzz.hf.forth;
public class MangoJuice extends Juice {
@Override
public void prepare() {
// TODO Auto-generated method stub
}
@Override
public void make() {
// TODO Auto-generated method stub
}
@Override
public void box() {
// TODO Auto-generated method stub
System.out.println("MangoJuice is OK!");
}
}
package cn.lzz.hf.forth;
public class OrangeJuice extends Juice {
@Override
public void prepare() {
// TODO Auto-generated method stub
}
@Override
public void make() {
// TODO Auto-generated method stub
}
@Override
public void box() {
// TODO Auto-generated method stub
System.out.println("OrangeJuice is OK!");
}
}
package cn.lzz.hf.forth;
public class WatermelonJuice extends Juice {
@Override
public void prepare() {
// TODO Auto-generated method stub
}
@Override
public void make() {
// TODO Auto-generated method stub
}
@Override
public void box() {
// TODO Auto-generated method stub
System.out.println("WatermelonJuice is OK!");
}
}
代码看起来还不错,但是如果有新的果汁类型加入就需要改变orderJuice方法中的代码。根据封装变化的原则,把创建Juice的代码封装到一个单独的方法中。下面就是用简单工厂改良后的代码实现:
public class SimpleJuiceStore {
private SimpleJuiceFactory simpleJuiceFactory;
public SimpleJuiceStore(SimpleJuiceFactory simpleJuiceFactory){
this.simpleJuiceFactory= simpleJuiceFactory;
}
/**
* 生产果汁方法
* @param name
* @return
*/
public Juice orderJuice(String name){
Juice juice=simpleJuiceFactory.createJuice(name);
juice.prepare();
juice.make();
juice.box();
return juice;
}
}
package cn.lzz.hf.forth;
public class SimpleJuiceFactory {
/**
* 创建果汁对象
* @param name
* @return
*/
public Juice createJuice(String name){
Juice juice=null;
switch(name){
case "mango":
juice=new MangoJuice();
break;
case "orange":
juice=new OrangeJuice();
break;
case "watermelon":
juice=new WatermelonJuice();
break;
default:
return null;
}
return juice;
}
}
工厂方法模式定义了一个创建对象的接口,但由子类决定需要实例化的类是那一个。工厂方法模式把实例化推迟到了子类。代码实现如下:
package cn.lzz.hf.forth;
public abstract class JuiceStore {
/**
* 预订果汁方法
* @param name
* @return
*/
public Juice orderJuice(String name){
Juice juice=createJuice(name);
juice.prepare();
juice.make();
juice.box();
return juice;
}
public abstract Juice createJuice(String name);
}
package cn.lzz.hf.forth;
public class CQJuiceStore extends JuiceStore {
@Override
public Juice createJuice(String name) {
// TODO Auto-generated method stub
Juice juice=null;
switch(name){
case "mango":
juice=new MangoJuice();
break;
case "orange":
juice=new OrangeJuice();
break;
case "watermelon":
juice=new WatermelonJuice();
break;
default:
return null;
}
return juice;
}
}
抽象工厂模式提供一个接口,用于创建相关或依赖的对象,而不需要明确指定具体类型。代码实现如下:
package cn.lzz.hf.forth;
public abstract class JuiceStore {
private IJuiceFactory juiceFactory;
public JuiceStore( IJuiceFactory juiceFactory ){
this.juiceFactory=juiceFactory;
}
public JuiceStore(){
}
/**
* 预订果汁方法
* @param name
* @return
*/
public Juice orderJuice(String name){
Juice juice=juiceFactory.createJuice(name);
juice.prepare();
juice.make();
juice.box();
return juice;
}
public abstract Juice createJuice(String name);
}
package cn.lzz.hf.forth;
public interface IJuiceFactory {
/**
* 创建果汁对象
* @param name
* @return
*/
Juice createJuice(String name);
}
package cn.lzz.hf.forth;
public class CQJuiceFactory implements IJuiceFactory {
@Override
public Juice createJuice(String name) {
// TODO Auto-generated method stub
Juice juice=null;
switch(name){
case "mango":
juice=new MangoJuice();
break;
case "orange":
juice=new OrangeJuice();
break;
case "watermelon":
juice=new WatermelonJuice();
break;
default:
return null;
}
return juice;
}
}
总结
对于简单工厂模式来说,把容易变化的创建对象代码封装到单独的方法中,提高程序的维护性,降低耦合度,增加代码复用性。
工厂方法模式通过继承的方式,让子类去实现各自的实例化对象的代码,超类不用关心子类的具体实现。
抽象工厂模式定义接口来创建对象,由不同的子类工厂去实现需要创建什么样的具体对象,超类不用关心创建的具体是什么对象。