工厂模式是使用频率很高的一种设计模式,在面试中也常常问到,今天咱们就来学习它。面试
解答这个问题前,咱们先来了解什么是工厂模式。设计模式
工厂模式其实也称建立模式,是用于建立对象的一种方式。本质上就是用工厂方法来代替new实例化对象。框架
举个例子:咱们在编写代码的时候,在一个A类中经过new的方式实例化了类B,那么A类和B类之间就存在耦合,若是之后修改了B类的代码和使用方式,例如须要在构造函数中传入参数,那么A类也就须要跟着修改了,一个类的依赖可能影响不大,但如有多个类依赖了B类,那么这个工做量将会至关的大,这无疑是件很是痛苦的事。这种状况下,咱们须要把建立实例的工做单独分离,与调用方解耦,也就是使用工厂方法建立实例的工做封装起来。这样咱们在须要调用对象的时候就不须要关心那些复杂的实例化问题。函数
工厂模式可分为两类:简单工厂模式和工厂模式。学习
定义一个接口和实现类,创建一个工厂类这些实现类进行实例的建立。测试
咱们用球来举例,定义一个基本的接口Ball,和一个抽象方法Play (玩),设计
public interface Ball { void play(); }
建立一个篮球的类和一个足球的类,并实现该接口,code
public class BasketBall implements Ball { public void play() { System.out.println("打篮球~~~"); } }
public class FootBall implements Ball { public void play() { System.out.println("踢足球~~~"); } }
而后,建立一个工厂类,能够用于生产篮球或者足球,对象
public class BallFactory { public Ball produce(String type) { if ("basketball".equals(type)) { return new BasketBall(); } else if ("football".equals(type)) { return new FootBall(); } return null; } }
工厂类建好之后,咱们就能够实例化工厂类,并调用 produce 方法来建立对应的实例对象,blog
public static void main(String[] args) { BallFactory factory = new BallFactory(); Ball ball = factory.produce("basketball"); ball.play(); }
结果输出:打篮球~~~
这就是简单工厂模式的基本实现,用关系图来表示就是:
这种模式的优势是代码简单,可以根据具体的参数返回对应的实例对象。
固然缺点也很明显,就是工厂类集中了全部实例的建立逻辑,若是增长业务就要多出相应的工厂方法,不只代码可能变得臃肿,也容易违反GRASPR的高内聚的责任分配原则
又称多态性工厂模式,是对简单工厂模式的改进。工厂模式中,一个子类对应一个工厂类,这些工厂类都实现了一个工厂接口。这至关于把一个简单工厂类拆分红多个工厂,这样代码就不会都耦合在同一个类里了。
具体的产品接口和实现类仍是复用上面的代码,咱们只需关注工厂方法的逻辑便可,
先建立一个工厂的接口
public interface IFactory { void produce(); }
而后建立对应业务的工厂类
public class BasketFactory implements IFactory { public Ball produce() { return new BasketBall(); } }
public class FootFactory implements IFactory { public Ball produce() { return new FootBall(); } }
测试代码
public static void main(String[] args) { BasketFactory basketFactory = new BasketFactory(); Ball basket = basketFactory.produce(); FootFactory footFactory = new FootFactory(); Ball foot = footFactory.produce(); basket.play(); foot.play(); }
输出结果是:
打篮球~~~ 踢足球~~
如上所示,若是须要添加新的产品,如排球,咱们就多写一个工厂类便可,这样就不会把全部的业务都耦合到一个工厂类中了,用关系图表示以下:
最后,总结一下工厂模式的优势吧,
一、良好的封装性,代码结构清晰,调用者只需知道产品的类名便可,不须要知道建立对象的过程,下降代码间的耦合。
二、扩展性优秀,若是增长一个产品类,只需增长一个对应的工厂类。
三、屏蔽产品类。产品类的实现如何变化,调用者都不须要关心,只需关心产品的接口,只要接口保持不变,系统中的上层模块就不会发生变化。
四、工厂模式是典型的解耦框架,高层模块只须要知道产品的抽象类,其余的实现类都不须要关心,符合迪米特法则,符合依赖倒置原则,符合里氏替换原则。
参考:
《设计模式之禅》