简单工厂模式(如下统一简称“工厂模式”)是一种建立型模式,因此是被用来建立对象的,也是最常使用的一种设计模式。它为建立各类复杂的大对象提供了简便的方式。在工厂模式中,咱们在建立对象时不会对客户端暴露建立逻辑,而是经过使用一个统一的出口来建立的对象。java
联想:生活中的工厂,工厂里有不少流水线,能够生产不一样的产品,而一个工厂和这些产品必定是属于同一个类型的。好比汽车工厂生产的是各类汽车,它确定不会生产食品,甚至是汽车零件!汽车的零件是由零件加工工厂生产的,汽车工厂只负责装配。而对买方来讲,买房只须要告诉工厂须要什么,工厂自会为其生产,而不须要知道生产的细节。数据库
开发过程当中老是伴随着建立大量的对象,当有些对象比较复杂庞大而且高度类似(具备相同的功能)的时候,咱们就能够采用工厂模式统一管理这些对象的建立。这对调用者来讲更加的方便直观,并且也更加安全,由于工厂是预先设计好的,当知足工厂的生产条件后才会生产产品。相反,若是是比较简单的对象,那就彻底不必采起这种方式,直接new就好了。设计模式
工厂模式大多在框架中常见,由于它主要是为调用者(咱们这些普通的开发人员)提供一个建立对象的出口,这些工厂类最大的特色就是它们的名字很明显—xxxFactory。例如链接各类数据库的ConnectionFactory,日志的LoggerFactory,Spring中核心的BeanFactory等等。固然,咱们也能够本身设计出工厂类来管理本身的对象。安全
理论和生活中的例子说完了,接下来步入正题,怎么在代码中去使用工厂模式。其实每种设计模式都能在生活中找到它们的例子,固然更能够说代码自己就是现实的一种抽象。上面说到,当一些对象高度类似即具备相同功能的时候,就可使用工厂模式去建立。而具备某种功能在Java中就是实现某个接口,因此是经过一些类共同实现某个接口,再由一个工厂类根据不一样的条件(参数)来建立相应的对象。而返回的是接口类型,也就是说仍是一个抽象,这时调用接口里定义的方法,根据Java的多态机制,会准确找到实现类并执行方法。这样还有一个好处就是扩展性比较好,当有新的需求的时候就加一个实现类。框架
下面以一个手机工厂为例子,经过UML类图和示例代码介绍工厂模式是如何设计并工做的。ide
1. 建立Mobile接口,并定义一个use的抽象方法spa
Mobile.java设计
public interface Mobile { void use(); }
2. 建立实现该接口的各个实现类日志
Iphone.javacode
public class IPhone implements Mobile { @Override public void use() { System.out.println("装逼"); } }
Nokia.java
public class Nokia implements Mobile{ @Override public void use() { System.out.println("挡子弹"); } }
Samsung.java
public class Samsung implements Mobile { @Override public void use() { System.out.println("爆炸"); } }
3. 建立一个手机工厂类MobileFactory,提供一个统一的出口getMobile方法来根据不一样的条件建立相应的对象
MobileFactory.java
public class MobileFactory { public Mobile getMobile(String brand) { if (brand == null) { return null; } switch (brand) { case "iPhone" : return new IPhone(); case "Nokia" : return new Nokia(); case "Samsung" : return new Samsung(); default: throw new RuntimeException("本工厂暂不生产此品牌的手机!"); } } }
这里咱们是根据不一样的品牌来建立对应的手机对象,而实际中的条件要稍微复杂一些。能够把方法改成static,这样使用工厂类建立对象就不用先new工厂对象,比较简单就不贴代码了。
4. 使用该工厂类,经过传递不一样的品牌参数来生成不一样的对象
public class FactoryPatternDemo { public static void main(String[] args) { Mobile iPhone = MobileFactory.getMobile("iPhone"); iPhone.use(); Mobile nokia = MobileFactory.getMobile("Nokia"); nokia.use(); Mobile samsung = MobileFactory.getMobile("Samsung"); samsung.use(); } }
5. 输出:
装逼 挡子弹 爆炸
当咱们须要实现某个明确的功能而这种功能一般具备广泛性时候,咱们就可使用工厂模式了。什么是广泛性呢,简单来讲就是这个功能提及来比较宽泛,可是实际上会有不一样的明确实现。仍是举一些例子:
例如要开发一个计算器,计算机的核心功能是计算,而计算这个功能是比较宽泛的,其实是有不少不一样的明确实现,最多见的就是加减乘除。这时就能够建立一个计算接口,再分别建立加减乘除四个实现类,最后建立一个计算器的工厂类,经过用户传来的运算符号决定具体采用哪一种运算。这样之后扩展计算器的功能,例如对数指数微积分等高级运算,就彻底能够按照这种模式去横向扩展。
再好比咱们的系统如今须要实现一个报警功能,当代码出现错误或系统崩溃时可以及时的通知相关人员。仍是老样子,报警提及来是一回事,但具体实现上有不一样的途径:邮件、短信、站内信等等。这时也能够采用工厂设计模式,根据不一样的状况采用不一样的报警。
解耦、方便调用者建立对象、扩展性好。
每新增一个功能,就要加一个实现类,并须要修改工厂类的出口方法。这无疑会增长系统的复杂度,不利于维护。