首页 > 代码库 > 工厂模式总结

工厂模式总结

工厂模式是用封装对象创建的,包括简单工厂模式、工厂模式、抽象工厂模式。

简单工厂模式:

依赖原则:单一职责,分离程序变和不变的部分。

实现方式:不算真正意义上的工厂,只是把目标中创建对象的方法抽取出来,放到一个类中集中处理

模式优点:1.将程序中创建对象部分分离出来,放入一个类中进行集中管理,方便维护;2.分离部分可以考虑使用配置方式进行维护

模式缺点:1.仍然先天性的保留大量对象创建判断逻辑;2.分离并不会提高效率;3.集中了所有对象创建逻辑,违反了高内聚责任分配原则

模式适用:1.程序中创建逻辑多,且需要频繁维护的;2.需要返回同一类对象,但只有运行是才知道需要具体返回对象;3.客户不关心对象如何创建

工厂方法模式:

依赖原则:依赖倒置,针对接口编程,分离程序变和不变的部分。

实现方式:将对象的细节处理延迟到子类中进行,使用抽象类,将需要具体处理的方法设置为抽象的,在子类中今夕实现

模式优点:延迟实例化;由子类决定具体处理逻辑;

模式缺点:重构工厂方法会破坏现有代码

模式适用:创建对象需要大量重复代码;创建对象需要某些信息而这些信息不应该包含在复合类中;创建对象需要集中管理以保证程序的一致性

抽象工厂模式:

依赖原则:针对接口编程,隐藏具体实现细节

实现方式:提供一个接口,用于创建依赖对象的家族而不需要指明具体类

模式优点:将具体产品从客户代码中分离出来,将同一类产品集中到一起

模式缺点:扩充新特性困难

模式适用:提供一个产品库


简单示例

以游戏中角色的生产技艺为基础做一个简单的分析,先上分析图


游戏中有战士、法师、牧师三种角色,每种角色对应一个技艺,战士--铸造,法师--缝纫,牧师--制药,每个技艺又可以细分出两个分支(见图),制作物品需要材料(图中未画出)

示例代码中,以战士---铸造--武器--剑类为例,使用简单工厂模式辅助产品和模型的获取,使用工厂方法模式定义武器工厂及其子类 剑工厂,使用抽象工厂模式定义武器--剑类及其使用的材料

目录结构如下


具体代码如下给出

package factorypattern.roles;

import factorypattern.skills.MakeException;
import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;

/**
 * 角色接口
 */
public interface Role {

	/**
	 * 生产
	 * 
	 * @param type
	 * @param pName
	 * @return
	 * @throws MakeException
	 * @throws NoSuchProductionException
	 */
	Production make(String type,String pName) throws MakeException, NoSuchProductionException ;
}

package factorypattern.roles;

import factorypattern.skills.MakeException;
import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;
import factorypattern.skills.Skill;

/**
 * 角色:战士
 */
public class Warrior implements Role{

	private final Skill skill;
	
	public Warrior(Skill skill)
	{
		this.skill = skill;
	}
	
	@Override
	public Production make(String type,String pName) throws MakeException, NoSuchProductionException {
		return skill.product(type,pName);
	}

}

package factorypattern.skills;

/**
 * 技艺接口
 */
public interface Skill {

	Production product(String type,String pName) throws MakeException,NoSuchProductionException;
}

package factorypattern.skills;

/**
 * 抽象类工厂:产品类
 */
public interface Production {
	String getName();
}

package factorypattern.skills;

/**
 * 尚未学习生产技能抛出异常
 */
public class NoSuchProductionException extends Exception {

	private static final long serialVersionUID = 1705270808656089664L;
	
	public NoSuchProductionException(String skill)
	{
		super("尚未学习"+skill+"生产技能!");
	}
}

package factorypattern.skills;

/**
 * 没有相关技艺专精异常
 */
public class MakeException extends Exception {

	private static final long serialVersionUID = -8191272257834156731L;

	public MakeException()
	{
		super("没有该技艺专精,无法进行制作");
	}
}

package factorypattern.skills.cast;

import factorypattern.skills.MakeException;
import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;
import factorypattern.skills.Skill;

/**
 * 简单工厂模式:铸造技能
 */
public class Cast implements Skill{

	@Override
	public Production product(String type,String pName) throws MakeException, NoSuchProductionException {
		return ContrlCenter.getProduction(type, pName);
	}

}

package factorypattern.skills.cast;

import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;
import factorypattern.skills.cast.sword.Sword;

/**
 * 工厂模式:武器工厂
 * 
 * 由子类决定武器模型
 * 这个例子中只写了剑类工厂,还有匕首类工厂,长兵类工厂....
 */
public abstract class WarponFactory {
	
	public Production getCasting(String pName) throws NoSuchProductionException
	{
		Sword p = getModel(pName);
		
		p.setOre();
		p.setFur();
		p.melt();
		p.casting();
		p.quench();
		p.hilt();
		
		return p;
	}
	
	protected abstract Sword getModel(String pName) throws NoSuchProductionException;
}

package factorypattern.skills.cast;

import factorypattern.skills.MakeException;
import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;
import factorypattern.skills.cast.sword.BlueWaveSword;
import factorypattern.skills.cast.sword.CrystalSword;
import factorypattern.skills.cast.sword.IronSword;
import factorypattern.skills.cast.sword.Sword;
import factorypattern.skills.cast.sword.SwordFactory;

/**
 * 简单工厂模式具体处理类
 * 
 * 集中处理各种细节,可以使用xml方式进行集中配置
 */
public class ContrlCenter {

	/**
	 * 获取产品
	 * 
	 * @param type
	 * @param pName
	 * @return
	 * @throws NoSuchProductionException
	 * @throws MakeException
	 */
	public static Production getProduction(String type,String pName) throws NoSuchProductionException, MakeException
	{
		Production p = null;
		
		if("warpon".equals(type))
		{
			WarponFactory f = new SwordFactory();
			p = f.getCasting(pName);
		}
		else if("jewelry".equals(type))
		{
			//暂不实现该分支
		}
		else
		{
			throw new MakeException();
		}
		
		return p;
	}
	
	/**
	 * 获取模型
	 * 
	 * @param pName
	 * @return
	 * @throws NoSuchProductionException
	 */
	public static Sword getModel(String pName) throws NoSuchProductionException {
		
		Sword p = null;
		
		if("ironSword".equals(pName))
		{
			p = new IronSword();
		}
		else if("blueWaveSword".equals(pName))
		{
			p = new BlueWaveSword();
		}
		else if("crystalSword".equals(pName))
		{
			p = new CrystalSword();
		}
		else
		{
			throw new NoSuchProductionException(pName);
		}
			
		return p;
	}
}

package factorypattern.skills.cast.sword;

import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.cast.ContrlCenter;
import factorypattern.skills.cast.WarponFactory;

/**
 * 简单工厂模式:剑类工厂
 */
public class SwordFactory extends WarponFactory{
	
	@Override
	protected Sword getModel(String pName) throws NoSuchProductionException {
		
		return ContrlCenter.getModel(pName);
	}
}

package factorypattern.skills.cast.sword;

import factorypattern.skills.Production;
import factorypattern.skills.meterial.fur.Fur;
import factorypattern.skills.meterial.ore.Ore;

/**
 * 抽象工厂:剑类
 * 
 * 由具体子类决定铸造使用材料【子类并没有决定权,实际上是使用了什么子类,其材料就已经设置好了】
 */
public abstract class Sword implements Production{

	protected String name;//剑名称

	protected Ore ore; //合成矿石
	protected Fur fur; //辅助皮革
	
	@Override
	public String getName() {
		return name;
	}
	
	/**
	 * 准备矿石
	 */
	public abstract void setOre();
	
	/**
	 * 准备皮革
	 */
	public abstract void setFur();
	
	/**
	 * 熔炼
	 */
	public void melt()
	{
		System.out.println("熔化矿石:"+ore.getName());
	}
	
	/**
	 * 浇铸
	 */
	public void casting()
	{
		System.out.println("浇铸");
	}
	
	/**
	 * 淬火
	 */
	public void quench()
	{
		System.out.println("淬火");
	}
	
	/**
	 * 装饰成型
	 */
	public void hilt()
	{
		System.out.println("使用"+fur.getName()+"制作剑柄");
	}
}

package factorypattern.skills.cast.sword;

import factorypattern.skills.meterial.fur.PigFur;
import factorypattern.skills.meterial.ore.IronOre;

/**
 * 剑类:铁剑
 */
public class IronSword extends Sword{
	
	public IronSword()
	{
		name = "铁剑";
	}

	@Override
	public void setOre() {
		this.ore = new IronOre();
	}

	@Override
	public void setFur() {
		this.fur = new PigFur();
	}
	
}

package factorypattern.skills.cast.sword;

import factorypattern.skills.meterial.fur.SilveryFoxFur;
import factorypattern.skills.meterial.ore.CrystalOre;

/**
 * 剑类:水晶剑
 */
public class CrystalSword extends Sword {

	public CrystalSword()
	{
		this.name = "水晶剑";
	}
	
	@Override
	public void setOre() {
		this.ore = new CrystalOre();
	}

	@Override
	public void setFur() {
		this.fur = new SilveryFoxFur();
	}

}

package factorypattern.skills.cast.sword;

import factorypattern.skills.meterial.fur.DeerFur;
import factorypattern.skills.meterial.ore.BlueStoneOre;

/**
 * 剑类:碧波剑
 */
public class BlueWaveSword extends Sword {

	public BlueWaveSword()
	{
		this.name = "碧波剑";
	}
	
	@Override
	public void setOre() {
		this.ore = new BlueStoneOre();
	}

	@Override
	public void setFur() {
		this.fur = new DeerFur();
	}

}

package factorypattern.skills.meterial.fur;

/**
 * 皮革类材料接口
 */
public interface Fur {
	String getName();
}

package factorypattern.skills.meterial.fur;

/**
 * 皮革类:鹿皮
 */
public class DeerFur implements Fur {

	@Override
	public String getName() {
		return "鹿皮";
	}

}

package factorypattern.skills.meterial.fur;

/**
 * 皮革类:猪皮
 */
public class PigFur implements Fur {

	@Override
	public String getName() {
		return "猪皮";
	}

}

package factorypattern.skills.meterial.fur;

/**
 * 皮革类:银狐皮
 */
public class SilveryFoxFur implements Fur {

	@Override
	public String getName() {
		return "银狐皮";
	}

}

package factorypattern.skills.meterial.ore;

/**
 * 矿石类接口
 */
public interface Ore {
	String getName();
}

package factorypattern.skills.meterial.ore;

/**
 * 矿石类:铁矿石
 */
public class IronOre implements Ore {

	@Override
	public String getName() {
		return "铁矿石";
	}

}

package factorypattern.skills.meterial.ore;

/**
 * 矿石类:水晶矿石
 * @author Tony.Sun
 *
 */
public class CrystalOre implements Ore {

	@Override
	public String getName() {
		return "水晶矿石";
	}

}

package factorypattern.skills.meterial.ore;

/**
 * 矿石类:绿松石
 * @author Tony.Sun
 *
 */
public class BlueStoneOre implements Ore {

	@Override
	public String getName() {
		return "绿松石";
	}

}

package factorypattern.test;

import factorypattern.roles.Role;
import factorypattern.roles.Warrior;
import factorypattern.skills.MakeException;
import factorypattern.skills.NoSuchProductionException;
import factorypattern.skills.Production;
import factorypattern.skills.cast.Cast;

public class Test {

	public static void main(String[] args){
		Role warrier = new Warrior(new Cast());
		try {
			Production p1 = warrier.make("warpon","ironSword");
			infos("获得新物品:"+p1.getName());
			
			Production p2 = warrier.make("warpon","blueWaveSword");
			infos("获得新物品:"+p2.getName());
			
			Production p3 = warrier.make("warpon","crystalSword");
			infos("获得新物品:"+p3.getName());
		} catch (MakeException e) {
			e.printStackTrace();
		} catch (NoSuchProductionException e) {
			e.printStackTrace();
		}
	}

	public static void infos(String s)
	{
		System.out.println(s);
		System.out.println("------------------------------------------------");
	}
}


工厂模式总结