首页 > 代码库 > 深入浅出设计模式 ------ Factory Method(工厂方法)

深入浅出设计模式 ------ Factory Method(工厂方法)

1. 定义: 一个用于创建对象的接口, 让子类决定实例化哪个类。 工厂方法使一个类的实例化延迟到子类。 


2. 结构

技术分享


3. 参与者(如上图)

Product ---- 定义工厂方法所创建的对象接口

ConcreteProduct ---- 实现Product接口

Creator ---- 声明工厂方法, 该方法返回一个Product类型的对象

ConcreteCreator ---- 重新定义工厂方法返回一个ConcreteProduct实例



4. 实现


(1) 特例: 简单工厂(Simple Factory)又叫做静态工厂方法(Static Factory Method)

     结构:

技术分享

  

  代码:

接口 Tree

package com.wenniuwuren.simplefactory;
/**
 * 
 * @author wenniuwuren
 * 生产者抽象类
 */
public interface Tree {
    public String product();
}



真实Product: AppleTree

package com.wenniuwuren.simplefactory;
public class AppleTree implements Tree {

	@Override
	public String product() {
		return "Apple";
	}


}



真实Product: LemonTree

package com.wenniuwuren.simplefactory;
public class LemonTree implements Tree {

	@Override
	public String product() {
		return "Lemon";
	}


}



核心类: 对象生成工厂Creator

package com.wenniuwuren.simplefactory;
/**
 * 
 * @author wenniuwuren
 * 
 * 工厂(Creator)角色 :简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。
 * 工厂类可以被外界直接调用,创建所需的产品对象。
 *
 */
public class SomethingCreator {
	// 静态工厂   这就是为什么简单工厂又叫静态工厂方法
    public static Tree factory(String fruitType) throws Exception{
        if(fruitType.equals("Lemon")){
            return new LemonTree();
        }else if(fruitType.equals("Apple")){
            return new AppleTree();
        }else{
            throw new Exception("暂时不支持生产该类型产品");
        }
    }
}


测试类:

package com.wenniuwuren.simplefactory;

/**
 * 
 * @author wenniuwuren
 * 测试类
 */
public class Test {
    public static void main(String[] args) throws Exception {

    	String fruitType = "Lemon";
    	Tree tree = SomethingCreator.factory(fruitType);
    	System.out.println(fruitType + "Tree Product : " + tree.product());
    	
     	fruitType = "Apple";
    	tree = SomethingCreator.factory(fruitType);
    	System.out.println(fruitType + "Tree Product : " + tree.product());
    	
    	fruitType = "Pear";
    	tree = SomethingCreator.factory(fruitType);
    	System.out.println(fruitType + "Tree Product : " + tree.product());
    }
}


运行结果:

LemonTree Product : Lemon
AppleTree Product : Apple
Exception in thread "main" java.lang.Exception: 暂时不支持生产该类型产品
at com.wenniuwuren.simplefactory.SomethingCreator.factory(SomethingCreator.java:22)
at com.wenniuwuren.simplefactory.Test.main(Test.java:15)




(2) 一般情况就是本文开头提到的工厂模式(Factory Method)

可以想象, 如果水果种类很多的话, 上面的简单工厂SomethingCreator类会爆炸, 所以更一般的方法是工厂的具体实现也交给子类。


代码:

将上述SomethingCreator改为接口(面向接口编程是一种良好的OO习惯)

package com.wenniuwuren.factorymethod;

public interface SomethingCreator {
	
    public Tree factory(String fruitType) throws Exception;
    
}



工厂具体实现类:LemonCreator

package com.wenniuwuren.factorymethod;


public class LemonCreator implements SomethingCreator {

	@Override
	public Tree factory(String fruitType) throws Exception {
		if (fruitType.equals("Lemon"))
			return new LemonTree();
		else 
			throw new Exception("生产Lemon错误");
	}
	
}



工厂具体实现类:AppleCreator
package com.wenniuwuren.factorymethod;


public class AppleCreator implements SomethingCreator {

	@Override
	public Tree factory(String fruitType) throws Exception {
		if (fruitType.equals("Apple"))
			return new AppleTree();
		else 
			throw new Exception("生产Apple错误");
	}
	
}



Creator(本例中的:Tree、 AppleTree、 LemonTree)部分不用变化, 从上面的类图结构对比就能明显看出, 变化的只是Creator工厂部分。


测试类:

package com.wenniuwuren.factorymethod;

/**
 * 
 * @author wenniuwuren
 * 测试类
 */
public class Test {
    public static void main(String[] args) throws Exception {

    	String fruitType = "Lemon";
    	SomethingCreator somethingCreator = new LemonCreator();
    	Tree tree = somethingCreator.factory(fruitType);
    	System.out.println(fruitType + "Tree Product : " + tree.product());
    	
     	fruitType = "Apple";
     	somethingCreator = new AppleCreator();
    	tree = somethingCreator.factory(fruitType);
    	System.out.println(fruitType + "Tree Product : " + tree.product());
    	
    }
}


测试结果:

LemonTree Product : Lemon
AppleTree Product : Apple




5. 区别


-- 简单工厂

简单工厂方法中,包括一个“抽象产品类”(该类可以是接口Interface,也可以是实际的类Class),所有需要的产品类都是该“抽象产品类”的子类(如果是接口的话,那么就是说所有产品类都继承了该接口)。

简单工厂一般只包含一个具体的工厂类,由该工厂类生成所有的产品类的对象。

 

-- 工厂方法

抽象工厂中,包括“抽象工厂类”和“抽象产品类”,同时包含不只一个工厂类。所有的工厂类都必须是“抽象工厂类”的子类,所有的产品都必须是“抽象产品类”的子类。



-- 抽象工厂

抽象工厂和工厂方法很类似,区别如下: 

工厂方法模式:
一个抽象产品类,可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类只能创建一个具体产品类的实例。 

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。       
区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个




参考书籍:

                《设计模式 : 可复用面向对象软件的基础》

                《Effective Java》

                《Head First 设计模式》

深入浅出设计模式 ------ Factory Method(工厂方法)