本篇首发于牧码人博客转载请加上此标示。
序言:
最近开始了设计模式的学习,这篇讲的是工厂方法模式。 工厂方法模式是对简单工厂的一个衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。 说了这么多我们先来看看什么情况下使用工厂模式。
应用场景
第一种情况是对于某个产品,调用者清楚地知道应该使用哪个具体工厂服务,实例化该具体工厂,生产出具体的产品来。Java Collection中的iterator() 方法即属于这种情况。
第二种情况,只是需要一种产品,而不想知道也不需要知道究竟是哪个工厂为生产的,即最终选用哪个具体工厂的决定权在生产者一方,它们根据当前系统的情况来实例化一个具体的工厂返回给使用者,而这个决策过程这对于使用者来说是透明的。
工厂方法模式是在简单工厂模式的衍生,所以我们先来了解下什么是简单工厂。
简单工厂模式
- 首先先创建一个car的抽象类定义一个run方法
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:53
* @Description:
* @Version: 1.0
*/
public interface Car {
public void run();
}
- 创建实现类 具体的两个产品
宝马车实现类
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:54
* @Description: 宝马车
* @Version: 1.0
*/
public class BMWCar implements Car {
public void run() {
System.out.println("bao ma car is running");
}
}
路虎车实现类
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:56
* @Description:
* @Version: 1.0
*/
public class LandRoverCar implements Car {
public void run() {
System.out.println("LandRover car is runnning ");
}
}
- 创建汽车工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:57
* @Description:
* @Version: 1.0
*/
public class CarFactory {
public static Car createBMCar()
{
return new BMWCar();
}
public static Car createLandRoverCar()
{
return new LandRoverCar();
}
}
- 测试
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 11:12
* @Description: 简单工厂模式测试
* @Version: 1.0
*/
public class Test {
public static void main(String[] args) {
Car car = CarFactory.createBMCar();
car.run();
}
}
测试结果 : bao ma car is running
总体来说,工厂模式适合:凡是出现了大量的产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建。但是同时简单工厂存在于这几个缺点。
缺点:
-
工厂类集中了所有实例(产品)的创建逻辑,一旦这个工厂不能正常工作,整个系统都会受到影响;
-
违背“开放 - 关闭原则”,一旦添加新产品就不得不修改工厂类的逻辑,这样就会造成工厂逻辑过于复杂。
-
简单工厂模式由于使用了静态工厂方法,静态方法不能被继承和重写,会造成工厂角色无法形成基于继承的等级结构。
工厂方法的设计
- 解决了什么问题
简单工厂模式存在着不易扩展,违背开闭原则的致命缺点。所以工厂方法就是在简单工厂的模式上解决它不易于扩展的缺点。
- 类图
工厂方法的实现
- 抽象工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:57
* @Description:
* @Version: 1.0
*/
public interface CarFactory {
public Car createCar();
}
- 工厂实现类
宝马工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 11:01
* @Description: 宝马车制造工厂
* @Version: 1.0
*/
public class BMWCarFactory implements CarFactory {
public Car createCar() {
return new BMWCar();
}
}
、
路虎工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 11:02
* @Description: 路虎车制造工厂
* @Version: 1.0
*/
public class LandRoverCarFactory implements CarFactory {
public Car createCar() {
return new LandRoverCar();
}
}
余代码跟简单工厂一样没什么改变,这里不贴了。
总结:
这里这样设计的好处,就是如果需要加新产品,只需要新增实现类就行了,不需要去改原来的代码了。这就易于扩展,解决了简单工厂的缺点。
抽象工厂模式的实现
抽象工厂跟工厂方法模式一个本质就是,抽象工厂模式有一个超级工厂,就比如一个汽车配件制造厂,他可以制作几种品牌的车的配件,比如引擎,以及轮子。那么一个品牌一个配件就有一个单独的小厂。这样就能衍生出宝马车轮子制造厂,宝马引擎制造厂,路虎引擎制造厂,路虎轮子制造厂。具体的这个品牌的轮子引擎怎么做就在自己的实现类里。所以从这里看工厂方法跟抽象工厂个人觉得是非常像的。只是抽象工厂的源头是一个超级大厂,维护着若干个小厂。就算需求变了这边只需要改具体小厂的制作方法就行了。
- 超级大厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 10:57
* @Description:
* @Version: 1.0
*/
public interface CarFactory {
/**
* 创建引擎
* @return
*/
public Engine createEngine();
/**
* 创建轮子
* @return
*/
public Wheel createWheel();
}
- 具体工厂实现类
宝马车制造工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 11:01
* @Description: 宝马车制造工厂
* @Version: 1.0
*/
public class BMWCarFactory implements CarFactory {
public Engine createEngine() {
return new BMWEngine();
}
public Wheel createWheel() {
return new BMWheel();
}
}
路虎车制造工厂
/**
* @Auther: Jan 橙寂
* @Date: 2019-7-24 11:02
* @Description: 路虎车制造工厂
* @Version: 1.0
*/
public class LandRoverCarFactory implements CarFactory {
public Engine createEngine() {
return new LandRoverEngine() ;
}
public Wheel createWheel() {
return new LandRoverWheel();
}
}
接下来的就是实现具体的轮子类,引擎类跟上面没多大改变。所以我就不贴了。
从代码可以看出,如果产品的增加,我们就需要加实现类就行了。不管你是奥拓还是大众。但是这样创建产品的过程就非常复杂了。所以抽象工厂是真的工厂,工厂方法模式就相当于一条生产线。
总结
本文主要对于工厂模式进行了介绍主要介绍了简单工厂模式,工厂方法模式以及抽象工厂模式。不管是哪种方式,其实都是前辈们代码写多了的套路。所以这三种模式没有什么绝对不好,也没说哪个绝对好,在一些优秀的框架设计中,都是设计模式结合在一起,所以懂得的原理还是要灵活运用。本篇文章源码在git中。接下来我会继续对设计模式进行讲解。
源码下载github
注意:本文归作者所有,未经作者允许,不得转载