问题场景:
在Java开发中,我们经常碰到各种各样的依赖形式,比如A类需要调用B类的方法,那么我们最常见的做法就是直接new一个B对象,然后调用,行云流水,一气呵成~
但是舒服的背后,往往是无尽的痛苦,设想如果有一天业务升级了,我们不需要调用B类的方法,而是要用C类去替换B类,那么我们是不是只能把B类的地方都换成C类,一个还好,如果有成千上万个地方调用了B类,我的鬼鬼哦~心中一万头草泥马走过,删库走人 ? 唉,只能苦逼的慢慢改了
那么该如何规避此类问题呢?这时候,我们的主角简单工厂模式就出现了
问题分析:
之所以会出现上述问题,其根本原因在于,在代码中,A类直接通过B类的实例进行调用,我们称这种解耦方式为硬编码解耦,说到底,问题就是A的实现与B的创建结合在了一起,那么假设,如果B类是通过一个工具类进行获取,那么如果出现业务变化,我们只需要修改工具类中的代码,把return 的值从B类改成C类 ,问题就可以迎刃而解了~
以上就是我们的工厂模式,而工具类就是我们的工厂,一个创建对象的工厂。其实这种思想很常见,比如我们在开发一个类的时候,如果有一些代码经常会被重复使用,那么我们的第一想法就是把它提取出来,成立一个独有的方法,以后再需要这些代码的时候只需要调用方法就行了。
而工厂模式就是这样的思想,只不过,我们是直接封装成一个类。
废话不多少,直接上案例:
案例:
在程序中,有一个电脑类Computer需要依赖外设类,现在有两个做法:
一:直接让Conputer依赖一个Printer类(打印机)
二:让Computer依赖一个Output接口(外设)
显而易见,第二种方法更符合我们的开发习惯,而在本例中,如果使用简单工厂模式,将会更加利于系统的维护和拓展
思路:
采用第二种方式,在Computer类中设置一个Output引用,这样Computer类便只是与接口耦合,而在Computer中也不需要new一个Output对象,而是通过设立一个外设工厂类(OutputFactory)来提供外设实例。
光说不练等于零,现在直接上代码:
首先先创建我们的外设接口:
package com.lzy.simple_factory;
/***
* 外设接口类,所有外设必须实现这个接口
* @author Administrator
* */
public interface Out {
//输出
public void outPut();
//设置数据缓存
public void setMsg(String msg);
}
接着我们创建一个打印机类
package com.lzy.simple_factory;
//打印机类
public class Printer implements Out{
//打印机中的缓存信息
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
//打印
public void outPut(){
System.err.println(msg);
}
}
接下来创建我们的Computer类
package com.lzy.simple_factory;
/***
* 电脑类
*
* @author Administrator
* */
public class Computer {
private Out out;
public Computer() {
}
//获取外设
public Out getOut() {
return out;
}
//设置外设
public void setOut(Out out) {
this.out = out;
}
//输入字符
public void keyIn(String msg){
out.setMsg(msg);
}
//打印
public void print(){
out.outPut();
}
}
接下里是重头戏,对象工厂类:
package com.lzy.simple_factory;
/***
* 设计者模式之简单工厂模式
*
* 将依赖的对象通过创建工厂进行创建,无需进行new
*
* 让对象的调用者与对象的创建过程分离
*
* @author Administrator
*
* */
public class OutFactory {
public Out getOut(){
return new Printer();
}
}
万事俱备,下面就是测试了:
public static void main(String[] args) {
Computer computer = new Computer();
OutFactory factory = new OutFactory();
Out out = factory.getOut();
computer.setOut(out);
computer.keyIn("kinout");
computer.print();
}
输出结果如下所示:
kinout
加入有一天,我们的电脑升级了,需要一台更好的外设了,我们只需要在OutFactory中将getOut方法的返回值改为升级之后的类的实例就行了,是不是很简单咯