0. 前言
富士康大家都知道,它的工厂代工各种产品,比如手机、电视还有一些汽车组件等。那么在设计模式中的富士康模式又是什么呢?那就是工厂模式,下面我就来介绍一下工厂模式中简单的一种,那就是简单工厂模式
1. 场景问题
每个设计模式被创造出来的时候都是为了解决某些问题,所以在介绍简单工厂模式前,我先引出一个问题先。
大家先可以回想一下接口的作用,总结起来就是“封装隔离”。
- 封装:简单来说就是对具体实现的功能封装。
- 隔离:简单来说就是让外部调用时,隔离了外部调用和具体实现。
那么使用接口又什么好处呢?
- 我的理解是首先它定义了一种规范,只有满足这个规范的东西才能作用于一个特定地方,比如说鼠标和键盘的插头都满足电脑USB接口的规范,所以它们能被电脑用。
- 再然后就是易扩展,给电脑一个USB接口,本来只是为了给鼠标用的,后来我又想用键盘,于是我又找到一个键盘,然后只要这个键盘符合我电脑的USB接口就好了,这不就平滑地扩展了嘛。
但是接口的使用还是会一点问题,我就用上面的例子用代码实现一下。
首先我有一个USB接口,定义一个fun方法
public interface USB {
void fun();
}
鼠标类Mouse,实现USB接口
public class Mouse implements USB{
@Override
public void fun() {
System.out.println("我是鼠标,可以插USB接口给电脑用哟~");
}
}
键盘类Keyboard,实现USB接口
public class Keyboard implements USB{
@Override
public void fun() {
System.out.println("我是键盘,可以插USB接口给电脑用哟~");
}
}
电脑类Computer,有个UseUSB方法,参数一个实现了USB的类的对象
public class Computer {
public void UseUSB(USB dev){
dev.fun();
}
}
好了,现在假设我的电脑要用一个鼠标,那么主类就可以这种写
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
USB dev = new Mouse();
computer.UseUSB(dev);
}
}
输出结果
我是鼠标,可以插USB接口给电脑用哟~
现在如果我的电脑要用键盘,主类只需要改一个地方,就是USB dev = new Mouse();改为USB dev = new Keyboard();这样子就不用改Computer类的UseUSB方法了,这不就体现了上面说的易扩展了咩~
那么现在问题来了,虽然我不用改Computer类了,但是我还是得改变使用者的一句代码呀。要是很多地方都有用到,那不是要改到疯!而且还破坏了封装性,在接口的封住隔离思想上,使用者不应该知道该接口的具体实现类的。所以这个时候简单工厂模式就登场了
2. 简单工厂模式
2.1 定义
提供一个创建对象实例的功能,而无须关心其具体实现。被创建实例的类型可以是接口、抽象类,也可以是具体的类。
2.2 说明
既然就简单工厂模式,那肯定是跟工厂有关的,那么工厂又有什么特点呢?
- 生产东西
- 对使用者隐藏了产品的具体生产
Talk is cheap. Show me the code,我还是直接写代码用简单工厂模式重现一下上面的例子吧
~
2.3 重写实例
现在我增加一个工厂类DevFactory,专门生产实现了USB接口的设备,如生产鼠标
public class DevFactory {
public static USB createDev(){
return new Mouse();
}
}
那么主类调用就是这样子的
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
USB dev = DevFactory.createDev();
computer.UseUSB(dev);
}
}
输出结果
我是鼠标,可以插USB接口给电脑用哟~
那现在假设我现在生产的鼠标质量不好,我要重新生产更好的鼠标,即鼠标类Mouse改变了,比如要生产BetterMouse,那么就不用改每个使用者的代码了,直接在工厂类中改一下就好了,是不是方便很多呢~
现在又有一个问题,一个工厂只生产鼠标恐怕是太low了吧,不行,我还要生产键盘。那就可以这样子实现工厂类,给创建对象的方法传递一个参数,来选择要生产什么设备。
public class DevFactory {
// 代表选择鼠标
public static final int MOUSE = 1;
// 代表选择键盘
public static final int KEYBOARD = 2;
/**
* 生产产品
*/
public static USB createDev(int type) {
// 选择生产的产品
switch (type) {
case MOUSE:
return new Mouse();
case KEYBOARD:
return new Keyboard();
default:
return null;
}
}
}
主类调用方法获取键盘类对象
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
USB dev = DevFactory.createDev(DevFactory.KEYBOARD);
computer.UseUSB(dev);
}
}
输出结果
我是键盘,可以插USB接口给电脑用哟~
这样子,就用简单工厂模式把例子重写了,是不是体验到了简单工厂的好处了呢。
3. 优缺点
每个东西都有好有坏,简单工厂模式也不例外。
优点:
帮助封装组件,并且实现了使用者与具体实现类的解耦。
缺点:可能增加使用者的复杂度,由于一个工厂类可创建的实现类的对象大多数时候都不可能只有一种,所以需要使用者通过参数来选择具体的实现类,那么使用者就必须得理解各个参数代表的具体功能与含义,这样子就增加了使用者的使用难度,也部分暴露了内部实现。而且破坏了开放-封闭原则,当有另外的实现类要加进来的时候,比如上面的键盘类,就要修改工厂类的代码。
如果上面的内容有错误的地方或者讲的不好的地方,还请大家指点一下,我好及时修改。