你真的会用简单工厂吗?

点击阅读原文更好的阅读体验web

前言

在项目中常常会碰到工厂模式,不光在项目中有在阅读源码的时候也必定少不了工厂模式。在咱们上上一篇文章分布式定时任务Quartz中建立触发器也是经过Quartz所提供的工厂来建立实例。可见工厂模式有多方便多经常使用。本文主要讲解简单工厂模式。设计模式

工厂模式[1](Factory Pattern)是 Java 中最经常使用的设计模式之一。这种类型的设计模式属于建立型模式,它提供了一种建立对象的最佳方式。微信

在工厂模式中,咱们在建立对象时不会对客户端暴露建立逻辑,而且是经过使用一个共同的接口来指向新建立的对象。app

介绍

工厂模式有三种分为简单工厂模式、厂方法模式、抽象工厂模式其中简单工厂模式并不属于GOF[2]所提出的23种设计模式之中,简单工厂模式其实更像是一种习惯。在设计模式之中工厂模式是属于建立型。框架

简单工厂模式

定义

简单工厂模式到底啥时候使用,还有就是为何要使用简单工厂模式呢?
首先在上面咱们说了工厂模式是建立型,在介绍的时候也说了它提供了一种建立对象的最佳方式也就是说简单工厂模式的定义就是由一个工厂对象来决定建立那种产品实例。其次就是何时使用简单工厂模式,首先如今有这样一个场景。小明决定去卖车,一种是奔驰一种是奥迪:编辑器

/**
* 小明要卖车
*/

/**
* 先生产奥迪
*/

AudiCar audiCar = new AudiCar();
/**
* 在生产奔驰
*/

MercedesCar mercedesCar = new MercedesCar();

而后发现本身生产成本过高,小明还要本身盯着各类细节。这并非小明想要的他只想赚个差价。这个时候就可使用简单工厂模式来帮助小明由于建立的对象比较少,而后工厂只须要知道须要什么就返回什么而后也不须要关心关键逻辑的时候就可使用简单工厂模式这就是简单工厂模式的使用场景,那我使用了简单工厂模式有啥优势呢?从上面简单的例子就能够知道客户端能够免除建立对象的责任直接交给工厂进行建立而后就是只须要知道传入的参数就能够获取到所须要的参数并且无需知道建立细节这不正是小明想要的吗?hahaha。注意:在强调一下简单工厂模式并不属于23种设计模式,它只是一种编码风格和实现分布式

案例

看完上面你就已经知道何时用简单工厂模式还有就是知道了它的优势和使用场景,那么如今就开始实战。在建立以前要知道简单工厂模式有如下几种角色。而后定义一个抽象产品接口。ide

/**
* @Author :luomengsun.
* @Date :Created in 13:26 2020/1/5
* @Description
*/

public interface Car {
/**
* 输出简单信息
*/

void printInfo();
}

一开始定义的Audi和Mercedes就是咱们的具体产品,改造一下测试

public class AudiCar implements Car {
@Override
public void printInfo() {
System.out.println("生产了奥迪");
}
}
public class MercedesCar implements Car{
@Override
public void printInfo() {
System.out.println("生产了奔驰");
}
}

它们都实现了咱们的抽象产品接口(也可使用抽象类,可是尽可能使用面向接口),如今定义工厂类。flex

public class CarFactory {
public Car getCarFactory(String str){
Car car = null;
if("audi".endsWith(str)){
car = new AudiCar();
}else if("mercedes".equals(str)){
car = new MercedesCar();
}else {
System.out.println("没有定义产品");
}
return car;
}
}

而后咱们就在测试客户端里面经过工厂类来建立汽车。

public class TestClient {
public static void main(String[] args) {
/**
* 小明经过汽车工厂生产车
*/

CarFactory carFactory = new CarFactory();
/**
* 先生产奥迪
*/

Car car = carFactory.getCarFactory("audi");
car.printInfo();
}
}

这个时候控制台输出生产了奥迪。UML类图:

对比

上面就实现了简单工厂模式,咱们对比一下最开始的实现,在引入简单工厂模式以后客户端须要什么就直接告诉工厂就行,根本不须要咱们关心具体的细,实质上也就是对建立对象进行了封装。若是在举一个例子的话就好比咱们去肯德基去吃饭,咱们想要吃薯条直接在前台点就行,你会关心薯条是怎么生产的吗?并且在你点薯条以前你确定是知道有这个产品的,否则你怎么去下单?

缺点

上面把简单工厂模式夸了一大堆,那它都有啥缺点呢?你别说缺点还真的有,首先看一下咱们的工厂类。

public class CarFactory {

public Car getCarFactory(String str){
Car car = null;
if("audi".endsWith(str)){
car = new AudiCar();
}else if("mercedes".equals(str)){
car = new MercedesCar();
}else {
System.out.println("没有定义产品");
}
return car;
}
}

若是这个时候我想要增长宝马怎么办,确定要先建立一个具体产品,而后在修改工厂类的判断逻辑,这样就违反了开闭原则。并且工厂类集中了全部实例的建立逻辑,违反了高内聚低耦合的原则。
那么有没有一种方法能够不修改工厂类里面的逻辑的方法吗?这个确定是有的,咱们可使用反射来建立具体的产品。修改一下工厂类:

public class CarFactory {
public Car getCarFactory(Class c){
Car car = null;
try {
car = (Car) Class.forName(c.getName()).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return car;
}
}

代码实例

上面清楚了简单工厂模式接下来看一下简单工厂模式实际的运用。
在JDK中处理时间不光有Date这个类还有Calendar类,在Calendar类中就使用了简单工厂模式。看一下getInstance()方法里面的实现

public static Calendar getInstance()
{
return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
}

它在里面调用了createCalendar方法而后在createCalendar方法里面有如下实现,是否是很熟悉这里就是运用咱们一开始实现的简单工厂模式

总结

简单工厂模式类型是建立型,可是它不属于23种设计模式,它只是一种实现方法。运用场景建立的对象比较少,而后工厂只须要知道须要什么就返回什么而后也不须要关心关键逻辑的时候就可使用简单工厂模式,优势:客户端能够免除建立对象的责任直接交给工厂进行建立还有就是 只须要知道传入的参数就能够获取到所须要的参数并且无需知道建立细节。缺点就是违背了开闭原则还违反了高内聚低耦合的原则。

最后

开胃小菜已经奉上,下一篇来看工厂模式更高级的实现。欢迎关注转发,最后在附一个简单工厂模式的逻辑导图

参考资料

[1]

工厂模式介绍: 参考菜鸟教程

[2]

GOF: https://baike.baidu.com/item/GoF

推荐阅读



点击阅读原文,得到更多精彩内容




本文分享自微信公众号 - 乱敲代码(lqcoder)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索