情景对话,一篇带你参悟工厂模式

时间:2020-01-10 10:00:01 来源:刊布在线 当前位置:齐乐游 > 百科 > 手机阅读

作者 | Java圣斗士 | 原创图文,转载请注明出处

全文2000字,阅读大约需要10分钟,建议收藏

情景对话,一篇带你参悟工厂模式

哈喽,大家好,我是又皮又可爱的Java圣斗士,关注我,每天带你飞!

我:哎,小红,最近听说你面试被问到了工厂模式,怎么样?回答上来了吗?

小红:唉,不开心,之前没怎么准备设计模式的知识,上阵前一天才看过你的《情景对话,一篇带你参悟单例模式》,可是面试的时候却问了我工厂模式。

我:恩,严重超纲!哈哈哈。

小红:哈哈,行了,你就别拿我开涮了。面试回来之后,我总结了一下工厂模式,你看我说的对不对。

我:恩恩,亡羊补牢,为时不晚。

小红:工厂模式是一种创建型模式,所谓创建型模式就是创建对象的时候可以使用的一种模式。它解决的是接口选择问题。这种模式实现起来啊,我看甚至比单例模式还简单呢。

首先,第一步就是要创建一个接口,比如我以汽车Car作为这个接口:

public interface Car {
void drive();
}

然后,第二步就是对这个接口的具体实现,在实际生产中,往往会有很多个实现,这里我就以三种车作为实现:Benz(奔驰)、Audi(奥迪)、BMW(宝马)

public class Benz implements Car {
@Override
public void drive() {
System.out.println("奔驰在跑......");
}
}
public class Audi implements Car {
@Override
public void drive() {
System.out.println("奥迪在跑......");
}
}
public class BMW implements Car {
@Override
public void drive() {
System.out.println("宝马在跑......");
}
}

我:恩。

小红:接口及其实现类在工厂模式中称为产品族,创建完产品族之后,第三步,我们就需要一个对应于接口的工厂CarFactory用于生产不同的产品:

public class CarFactory {
public Car getCar(String car) {
if (car == null) {
return null;
}
switch (car) {
case "Benz":
return new Benz();
case "Audi":
return new Audi();
case "BMW":
return new BMW();
default:
break;
}
return null;
}
}

创建完工厂类之后,可以说工厂模式就已经完成了。如何使用,可以像下面Test类中的代码这样:

public class Test {
public static void main(String[] args) {
CarFactory factory = new CarFactory();
Car benz = factory.getCar("Benz");
Car audi = factory.getCar("Audi");
Car bmw = factory.getCar("BMW");
benz.drive();
audi.drive();
bmw.drive();
}
}

输出结果:

奔驰在跑......
奥迪在跑......
宝马在跑......

我:恩,是的,这就是工厂模式的基本实现,我来补充一下类图:

情景对话,一篇带你参悟工厂模式

小红:哇,这个类图也太形象了点吧。

我:嘿嘿,你既然知道了如何实现工厂模式,那你能说出工厂模式的优缺点吗?

小红:这个不知道啊。

我:工厂模式是通过一个工厂类来创建目标对象,其关键是通过条件判断将对象的名称字符串与对应的产品对象建立联系。而工厂类,你有没有注意到,其实就是在维护一个条件判断语句,或者是switch或者if-else

小红:哎!真的!

我:工厂模式最大的优点就是扩展性强,当我们需要添加新的产品类的时候,只需要让它实现产品族的上层接口,然后再在工厂类中加入一条判断语句就可以了,比如下面这样,我增加了一个五菱宏光

情景对话,一篇带你参悟工厂模式

public class WuLing implements Car {
@Override
public void drive() {
System.out.println("五菱宏光漂移过弯......");
}
}

小红:......

我:然后工厂类增加一条判断:

case "WuLing":
return new WuLing();

就可以在正常业务中使用了:

public static void main(String[] args) {
CarFactory factory = new CarFactory();
Car wuLing = factory.getCar("WuLing");
wuLing.drive();
}

输出结果:

五菱宏光漂移过弯......
情景对话,一篇带你参悟工厂模式

所以,工厂模式在很多不确定产品族范围的时候,用处很大,你只需要对原有产品族进行扩展,并在工厂中添加一条条件语句即可,扩展性非常强。

小红:的确,那工厂模式有什么缺点吗?

我:其实缺点就是增加了系统的复杂度,不过,在特定的时候使用工厂模式,可以简化系统的实现。比如,如果你的系统和某个第三方接口进行对接,双方对接的方案有两种,一种是通过不同的url来请求不同的接口,如果你有10个不同的业务种类请求,那么你就需要和对方约定10个不同的url,很明显,这种方案维护起来很不方便。

那么第二种方案就可以选择这种工厂模式,你只需要给第三方提供一个接口,然后在请求体中约定一个业务类型的字段,通过这个字段,来匹配不同的业务服务模块,这就是一种工厂模式的典型应用。是不是很方便?

小红:真的呢!

情景对话,一篇带你参悟工厂模式

我:工厂模式还有很多其他的应用场景,比如,你想设计一个连接服务器的框架,需要三个协议:POP3、IMAP、HTTP,那么你就可以将这三种服务设计为三个不同的产品类型,共同实现一个协议接口,那么这样的代码结构就非常实用了!如果你在未来还希望增加新的协议比如:websocket,就可以去实现协议接口,非常简单。

总之,工厂模式充分利用了继承与多态的特性多态的意义就是“一个接口,多个实现”,这里面还包括一个OOD设计原则中非常重要的里式替换原则,即:任何接收父类的地方,都应该能够接收子类型。换句话说如果使用的是一个基类的话,那么一定适用于其子类,而且程序察觉不出基类对象和子类对象的区别。

往期精彩:

对话式情景剖析,String被final修饰的真正原因!一篇足矣

教你如何优雅地用Java8 实现日期时间的操作

必考!Java参数传递的真正秘密

如何做到基础扎实?大牛说:玩好JDK

从小白到大牛:把学过的技能应用到项目中

---欢迎关注【Java圣斗士】,我是你们的小可爱(✪ω✪) Morty---

---专注IT职场经验、IT技术分享的灵魂写手---

---每天带你领略IT的魅力---

---期待与您陪伴!---

百科本月排行

百科精选