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