Java设计模式(3)之工厂方法模式&抽象工厂模式学习总结
2017-10-21 21:24
771 查看
工厂模式&抽象工厂模式
工厂模式主要用于实现将对象的实例化部分取出来,进而优化系统架构,增强系统的扩展性。工厂模式的适用场景:
1. 需要创建一组类似的对象,对应于需要生产一个产品族的不同产品; 2. 在编写代码时,不能预见需要创建哪种类的实例,即不能预见需要生产哪种产品;指定的类型由客户端的具体要求决定,从而实现功能的剥离; 3. 需要考虑系统的扩展性,系统的实现不能依赖于产品类实例如何被创建、组合及表达的细节;
工厂模式的作用:
使用工厂提供的方法代替new操作进行实例的获取;
工厂模式的目的:
①尽量使设计达到松耦合,即对象的变化不会影响到依赖于该对象的对象的变化,这也是为什么使用接口进行工厂模式设计的原因之一; ②剥离具体产品的生产与客户端,实现责任分割;即由客户端指定需要生产的具体产品,由工厂进行该产品的生产;
工厂模式的分类:
工厂方法模式和抽象工厂模式;
工厂模式和抽象工厂模式是在日常开发中使用非常广泛的设计模式。
两者的联系:
①工厂方法模式可以视为抽象工厂模式的一种特例;抽象工厂模式是工厂方法模式的扩展; ②工厂方法模式一般针对一个产品族的产品生产进行设计;抽象工厂模式一般针对多个产品族的产品的生产进行设计;
相关关键词:工厂类、产品族、系列
工厂模式的设计思路:
①定义一个稳定的公共接口作为产品族中的不同产品类的实现接口(产品族接口),把具体产品的实例化,放到工厂方法中进行实现; ②分别进行不同的产品类的设计,必须实现产品族接口; ③定义一个产品族的工厂类,该类主要提供获取不同种类产品的方法(工厂方法); 注意: ①这里的工厂方法的设计要尽可能地通用化,一般设计为只需要提供一个关键词就可以获取一个产品的工厂方法; ②这里的工厂方法可以使用反射机制进行设计,根据指定的产品类的类名进行对象的实例化; 为避免类名过长,可以通过映射简化类名,在properties文件中,进行关键词和类名的映射;
设计案例:
以最近比较火的手游王者荣耀作为例子,其中的英雄属于一个产品族,这个产品族中包含坦克类英雄、射手类英雄以及辅助类英雄等; 这里将英雄设计为一个接口HeroInterface;不同的英雄类通过实现该接口进行设计,生产不同类型英雄的工厂类提供工厂方法进行英雄的生产;
package design.pattern.hero; //英雄类公共接口 public interface HeroInterface { public HeroInterface produce(); } package design.pattern.hero; //坦克英雄类 public class TankHero implements HeroInterface { @Override public HeroInterface produce() { System.out.println("坦克型英雄"); //return new TankHero(); } package design.pattern.hero; //法 d1ce 师英雄类 public class MasterHero implements HeroInterface { @Override public HeroInterface produce() { System.out.println("法师型英雄"); //return new MasterHero(); } package design.pattern.hero; //辅助英雄类 public class AuxiliaryHero implements HeroInterface { @Override public HeroInterface produce() { System.out.println("辅助型英雄"); //return new AuxiliaryHero(); } } package design.pattern.hero; //生产英雄的工厂类 public class HeroFactory { //方法一:通过类型获取对应的英雄 public static HeroInterface produceHeroByType(String type) { if("Tank".equals(type)) { return new TankHero().produce(); }else if("Master".equals(type)) { return new MasterHero().produce(); }else if("Auxiliary".equals(type)) { return new AuxiliaryHero().produce(); } return null; } //方法二:通过类名获取相应类的英雄 public static HeroInterface produceHeroByClassName(String className) { try { HeroInterface hero = (HeroInterface) Class.forName(className).newInstance(); return hero.produce(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } //方法三:通过类名对应的关键字获取相应类的英雄 public static HeroInterface produceHeroByClassKey(String key) { try { Map<String, String> map = new PropertiesReader().getProperties(); HeroInterface hero = (HeroInterface) Class.forName(map.get(key)).newInstance(); return hero.produce(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } } package design.pattern.hero; import java.io.InputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import java.util.Properties; /** * properties文件的读取工具 * @author Administrator * */ public class PropertiesReader { public Map<String, String> getProperties() { Properties props = new Properties(); Map<String, String> map = new HashMap<String, String>(); try { InputStream in = getClass().getResourceAsStream("type.properties"); props.load(in); Enumeration en = props.propertyNames(); while (en.hasMoreElements()) { String key = (String) en.nextElement(); String property = props.getProperty(key); map.put(key, property); } } catch (Exception e) { e.printStackTrace(); } return map; } } design.pattern.hero包下的type.properties文件: Tank=design.pattern.hero.TankHero Master=design.pattern.hero.MasterHero Auxiliary=design.pattern.hero.AuxiliaryHero
抽象工厂模式的设计思路:
抽象工厂模式一般适用于需要生产多个产品族的产品的场景;这里以最简单的(两个产品族)作为例子讲解: 产品族A和产品族B 系列X和系列Y ①分别设计对应于产品族A、B的产品族接口; ②根据系列的不同,将产品族A、B的产品类实现为不同系列下的产品类; ③设计一个包含获取产品族A、B的产品的方法的公共接口(产品族公共接口); ④基于实现产品族公共接口,进行不同系列下的工厂类的设计; 这里的工厂类依据不同的系列,分为两个工厂类(系列X、Y的工厂类); 系列X的工厂类的工厂方法用于生产系列X下的产品族A和产品族B的产品; 系列Y的工厂类的工厂方法用于生产系列Y下的产品族A和产品族B的产品;
设计案例:
基于上一个设计案例的背景,对英雄的皮肤进行进行抽象工厂模式的设计,同时增加国庆风格、中秋风格两个系列;英雄皮肤分为男式英雄皮肤和女式英雄皮肤,将其设计为接口HeroDressInterface、HeroineDressInterface;国庆风格下的实现类为NationalHeroDress、NationalHeroineDress;
中秋风格下的实现类为MAHeroDress、MAHeroineDress;国庆、中秋两个系列对应的皮肤工厂类分别为NationalFactory、 MAFactory;这两个工厂类都实现了皮肤工厂接口;
HeroDressInterface接口具体代码如下:
//男式英雄皮肤接口 public interface HeroDressInterface { public HeroDressInterface produceHeroDress(); }
HeroineDressInterface接口具体代码如下:
//女式英雄皮肤接口 public interface HeroineDressInterface { public HeroineDressInterface produceHeroineDress(); //国庆系列男式英雄皮肤类 public class NationalHeroDress implements HeroDressInterface { @Override public HeroDressInterface produceHeroDress() { System.out.println("国庆系列男式英雄皮肤"); } }
//国庆系列女式英雄皮肤 public class NationalHeroineDress implements HeroineDressInterface { @Override public HeroineDressInterface produceHeroineDress() { System.out.println("国庆系列女式英雄皮肤"); } }
//中秋系列男式英雄皮肤类 public class MAHeroDress implements HeroDressInterface { @Override public HeroDressInterface produceHeroDress() { System.out.println("中秋系列男式英雄皮肤"); } }
//中秋系列女式英雄皮肤 public class MAHeroineDress implements HeroineDressInterface { @Override public HeroineDressInterface produceHeroineDress() { System.out.println("中秋系列女式英雄皮肤"); } }
//皮肤的实现接口 public interface dressFactory { //获取男式英雄皮肤 public HeroDressInterface produceHeroDre(); //获取女式英雄皮肤 public HeroineDressInterface produceHeroineDre(); }
//国庆系列皮肤工厂类 public class nationalDressFactory implements dressFactory { @Override public HeroDressInterface produceHeroDre() { return new NationalHeroDress(); } @Override public HeroineDressInterface produceHeroineDre() { return new NationalHeroineDress(); } }
//中秋系列皮肤工厂类 public class maDressFactory implements dressFactory { @Override public HeroDressInterface produceHeroDre() { return new MAlHeroDress(); } @Override public HeroineDressInterface produceHeroineDre() { return new MAHeroineDress(); } }
相关文章推荐
- java设计模式学习笔记--抽象工厂模式
- java设计模式学习 ----- 抽象工厂模式(Abstract Factory)
- 设计模式学习总结-抽象工厂模式(Abstract Factory Pattern)
- Java设计模式之工厂方法、抽象工厂模式 程序 总结
- JAVA设计模式学习总结
- 设计模式学习总结-抽象工厂模式(Abstract Factory Pattern)
- Java设计模式—工厂方法模式&抽象工厂模式
- Java中的设计模式学习总结(二)---单例模式
- 黑马程序员--Java学习日记之总结复习(多线程和设计模式)
- 设计模式学习总结1 - 创建型1 - Abstract Factory抽象工厂模式
- java/android 设计模式学习笔记(4)---抽象工厂模式
- java的设计模式,学习心得总结-工厂模式
- java设计模式之抽象工厂模式学习
- java学习笔记-设计模式4(抽象工厂模式)
- java的设计模式,学习心得总结-工厂模式
- java设计模式学习笔记-抽象工厂模式
- java设计模式学习笔记--抽象工厂模式
- 关于java中static关键字在单态设计模式的应用学习和总结
- Java-马士兵设计模式学习笔记-总结
- JAVA设计模式学习6——抽象工厂模式