设计模式之工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
工厂模式分为三种:
1、普通工厂模式
就是建立一个工厂类,对实现了同一接口的一些类进行实例的创建。
接口
public interface Sender { public void send(); }
实现类1
public class MailSender implements Sender { @Override public void send() { System.out.println("this is MailSender!"); } }
实现类2
public class SmsSender implements Sender { @Override public void send() { System.out.println("this is SmsSender!"); } }
工厂类
public class SenderFactory { public Sender produce(String type){ if ("mail".equals(type)) { return new MailSender(); } else if("sms".equals(type)) { return new SmsSender(); } else { System.out.println("请输入正确的类型!"); return null; } } }
测试类
public class FactoryTest { public static void main(String[] args) { SenderFactory factory = new SenderFactory(); Sender sender = factory.produce("mail"); sender.send(); } }
2、多个工厂模式
是对普通工厂方法模式的改进,在普通工厂方法模式中,如果传递的字符串出错,则不能正确创建对象,而多个工厂方法模式是提供多个工厂方法,分别创建对象。
接口和实现类与 1 中一样,针对普通工厂模式的示例代码改进如下:
工厂类
public class SenderFactory { public Sender produceMail(){ return new MailSender(); } public Sender produceSms(){ return new SmsSender(); } }
测试类
public class FactoryTest { public static void main(String[] args) { SenderFactory factory = new SenderFactory(); Sender sender = factory.produceMail(); sender.send(); } }
3、静态工厂模式
是对多个工厂模式的改进,将上面的多个工厂模式里的工厂类里的工厂方法置为静态的,测试类就不需要创建实例,直接调用即可。
接口和实现类与 1 中一样,针对多个工厂模式的示例代码改进如下:
工厂类
public class SenderFactory { public static Sender produceMail(){ return new MailSender(); } public static Sender produceSms(){ return new SmsSender(); } }
测试类
public class FactoryTest { public static void main(String[] args) { Sender sender = SenderFactory.produceMail(); sender.send(); } }
4、反射工厂模式
以上三种工厂模式每增加一个产品时,都必须增加一个实现类,并且需要对工厂类进行修改(修改或增加工厂方法),如果使用反射的话,只需要增加一个实现类就可以了,工厂类不需要进行修改。
接口和实现类与 1 中一样,针对以上工厂模式的示例代码改进如下:
工厂类
public class SendFactory { @SuppressWarnings("unchecked") public static <T> T getClass(Class<? extends T> clazz){ T obj = null; try { obj = (T) Class.forName(clazz.getName()).newInstance(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return obj; } }
测试类
public class FactoryTest { public static void main(String[] args) { MailSender mailSender = SendFactory.getClass(MailSender.class); mailSender.send(); } }
总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂模式进行创建。