工厂模式是用封装对象创建的,包括简单工厂模式、工厂模式、抽象工厂模式。
简单工厂模式:
依赖原则:单一职责,分离程序变和不变的部分。
实现方式:不算真正意义上的工厂,只是把目标中创建对象的方法抽取出来,放到一个类中集中处理
模式优点: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("------------------------------------------------");
}
}