升级版的工厂模式(外联配置文件+内用反射),体现多态好处(^-^)
工厂模式作用:根据种类生产出对应的类对象
✿ 简单模式:
简单模式:传入参数(type,对象的构造方法的一些参数) switch(type): case type1: return 对象1; case type2: return 对象2; case type3: return 对象3; ……
✿ 升级版工厂模式:
升级版工厂模式(外联配置文件+内用反射):传入参数(type,对象的构造方法的一些参数) //① 工厂类通过配置对象通过输入流(输入流是通过类的字节码文件对象class的加载器,然后以流的方式获取资源),加载配置文件到静态代码块(ps:这里的类加载器是扩展类加载器) 配置对象.load(类.class.getClassLoader( ). getResourceAsStream(“配置文件所在路径”); //②反射,获得字节码文件对象,即类的Class 对象 Class<?> heroClass = Class.forName(“类名”); //③ 构造方法实例化对象,分有参、无参构造方法 // ▪无参,直接通过heroClass.newInstance(); 返回类对象 // ▪有参,需要先实例化一个带什么类型参数的构造方法对象Constructor,然后再通过构造方法对象.newInstance(参数); Constructor constructor = heroClass.getConstructor(参数类的class); return constructor.newInstance(参数);
小项目代码论证:工厂模式的好处,多态的可升级可维护!
❀英雄类Hero
package PolymorphicFunction; /** * 英雄类 * @author Huangyujun * */ public abstract class Hero { private String name; //英雄名称 private double attack; //攻击力 private String weaponName; //武器名称 public Hero(String name, double attack, String weaponName) { super(); this.name = name; this.attack = attack; this.weaponName = weaponName; } //攻击方法 public abstract void attack(); public String getName() { return name; } public void setName(String name) { this.name = name; } public double getAttack() { return attack; } public void setAttack(double attack) { this.attack = attack; } public String getWeaponName() { return weaponName; } public void setWeaponName(String weaponName) { this.weaponName = weaponName; } }
❀战士类Warrior
package PolymorphicFunction; /** * 战士类 * @author Huangyujun * */ public class Warrior extends Hero{ public Warrior(String name, double attack,String weaponName) { super(name, attack, weaponName); } @Override public void attack() { System.out.println("战士"+ getName() + "举起"+ getWeaponName() +"保家卫国,奋斗到底!"); } }
❀英雄工厂类 HeroFactories
package PolymorphicFunction; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Properties; /** * 英雄工厂类,为了免去升级类时修改工厂类的代码,需要使用配置对象加载配置文件 * 相当于借力,通过配置对象把配置文件和工厂类联系起来,修改配置文件起到了改变工厂类的数据(而不用为了不同数据,为了适用该数据,再去修改工厂) * @author Huangyujun * */ public class HeroFactories { private static Properties pro = new Properties(); //配置对象 /** *静态代码块,加载配置文件,通过流加载-流(路径) *技巧:通过类的class中的一些方法获取流的加载器,再获得流 */ static { try { //注意配置文件路径 pro.load(HeroFactories.class.getClassLoader().getResourceAsStream("PolymorphicFunction/Properties.properties/Pro.properties")); //测试一下,加载是否成功 // System.out.println(pro.getProperty("warrior")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //静态方法,返回英雄子类 public static Hero getHeroType(String heroType, String HeroName, double attack, String weaponName) { String heroName = pro.getProperty(heroType); //反射,获得字节码文件对象,即类的Class 对象 try { Class<?> heroClass = Class.forName(heroName); //获取HeroClass构造方法对象 Constructor<Hero> heroConstructor = (Constructor<Hero>) heroClass.getConstructor(String.class,double.class,String.class); return heroConstructor.newInstance(HeroName,attack,weaponName); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } }
❀英雄工厂类 HeroFactories
package PolymorphicFunction; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Properties; /** * 英雄工厂类,为了免去升级类时修改工厂类的代码,需要使用配置对象加载配置文件 * 相当于借力,通过配置对象把配置文件和工厂类联系起来,修改配置文件起到了改变工厂类的数据(而不用为了不同数据,为了适用该数据,再去修改工厂) * @author Huangyujun * */ public class HeroFactories { private static Properties pro = new Properties(); //配置对象 /** *静态代码块,加载配置文件,通过流加载-流(路径) *技巧:通过类的class中的一些方法获取流的加载器,再获得流 */ static { try { //注意配置文件路径 pro.load(HeroFactories.class.getClassLoader().getResourceAsStream("PolymorphicFunction/Properties.properties/Pro.properties")); //测试一下,加载是否成功 // System.out.println(pro.getProperty("warrior")); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //静态方法,返回英雄子类 public static Hero getHeroType(String heroType, String HeroName, double attack, String weaponName) { String heroName = pro.getProperty(heroType); //反射,获得字节码文件对象,即类的Class 对象 try { Class<?> heroClass = Class.forName(heroName); //获取HeroClass构造方法对象 Constructor<Hero> heroConstructor = (Constructor<Hero>) heroClass.getConstructor(String.class,double.class,String.class); return heroConstructor.newInstance(HeroName,attack,weaponName); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } }
❀测试类test
package PolymorphicFunction; /** * 测试类 */ import java.util.Properties; public class test { public static void main(String[] args) { Hero hero1 = HeroFactories.getHeroType("warrior","铠甲", 80, "长戟"); hero1.attack(); } }
#key=value warrior=PolymorphicFunction.Warrior