若是作开发的工做,工厂设计模式大概都已经深刻人心了,比较常见的例子就是在代码中实现数据库操做类,考虑到后期可能会有数据库类型变换或者迁移,通常都会对一个数据库的操做类抽象出来一个接口,而后用工厂去获取实际数据库操做类实例。数据库
下面举一个最简单的工厂模式例子:设计模式
interface IAnimal { void talk(); } class Cat implements IAnimal { @Override public void talk() { System.out.println("I'm cat"); } } class Dog implements IAnimal { @Override public void talk() { System.out.println("I'm dog"); } } class AnimalFactory { private AnimalFactory() {} public static IAnimal getInstance(String animal) { if ("Cat".equals(animal)) { return new Cat(); } else if ("Dog".equals(animal)) { return new Dog(); } else { return null; } } } public class Main { public static void main(String[] args) throws ParseException{ IAnimal animal = AnimalFactory.getInstance("Cat"); animal.talk(); animal = AnimalFactory.getInstance("Dog"); animal.talk(); } }
最简洁的例子了, 客户端首先想要生成一个Cat的实例,传入“Cat”,一阵操做以后,又想生成Dog实例,直接传入“Dog”到工厂里面拿,接着继续使用。ide
观察工厂类,里面是根据客户端传过来的字符串手动new一个实例并返回,那若是这个工厂恰好要容纳好几百种实例的返回,并可能会不定时添加新的实例类型,那岂不是每次都要去修改工厂类,有没有一个办法我写一次工厂类,而后工厂类能自动产生并返回客户端须要的实例? 这个时候咱们能够利用反射的机制,根据客户端传进来的字符串,运用反射原理去寻找咱们所要的实体类。首先呢,接口和实体类都要写还给他的,接着呢修改工厂类以下:函数
class AnimalFactory { private AnimalFactory() {} public static IAnimal getInstance(String animal) { try { Class cls = Class.forName(animal); return (IAnimal) cls.newInstance(); } catch (Exception e) { return null; } } }
首先由Class类型的静态方法forName(String className)找到这个类并返回这个类的Class类型对象, 此时找不到的话会抛出ClassNotFoundException,抛出异常了就返回null咯。this
而后用Class对象的newInstance()方法产生一个实例,这个实例就是forName函数找到的实体类实例。至关于用默认构造函数产生一个实例,因此此处也会抛出异常,好比默认构造函数是私有类型的状况下。spa
接着,若是我产生的实例都须要根据传入的参数对应去实例化呢,这个时候,咱们能够利用反射去找有相应参数的构造函数,再生成一个实例就好啦。设计
interface IAnimal { void talk(); } class Cat implements IAnimal { private String name; public Cat(String name) { this.name = name; } @Override public void talk() { System.out.println("I'm cat:" + this.name); } } class Dog implements IAnimal { private String name; public Dog(String name) { this.name = name; } @Override public void talk() { System.out.println("I'm dog:" + this.name); } } class AnimalFactory { private AnimalFactory() {} public static IAnimal getInstance(String animal, String name) { try { Class cls = Class.forName(animal); Constructor<?> con = cls.getConstructor(String.class); return (IAnimal)con.newInstance(name); } catch (Exception e) { return null; } } } public class Main { public static void main(String[] args) throws ParseException{ IAnimal animal = AnimalFactory.getInstance("Cat", "Miao"); animal.talk(); animal = AnimalFactory.getInstance("Dog", "Wang"); animal.talk(); } }
在工厂类中,咱们若是找到这个类的Class类型对象时,就用这个Class对象去找对应的Constructor对象,getConstructor方法接受无数个参数,根据须要指定咱们要找的这个构造函数参数类型是什么,例子中这个类型是String,因此咱们用String.class去指定这个类型即是String类型,接着用这个Constructor对象,newInstance(String para)实例化并返回。code
至此,用反射改进传统工厂模式步骤完成。 若有写的不妥之处,欢迎之处斧正。对象
尊重知识产权,转载引用请通知做者并注明出处!blog