理解
工厂模式,作为一种对象创造型模式,也是我们很常用的设计模式,他将对象的使用和创建分离,让调用者不用关心对象是如何创造的。比如你去4S点买车,你只要跟老板说你是要保时捷卡宴,还是911就好了,不用关心这辆车是怎么造出来的。
作用
工厂模式剥离了对象的创建和使用,当业务发生变化时方便于代码的扩展和修改,比如你要注册一个账号,之前注册的是一个QQ账号,后来你想换个微信账号了,你不用对原来的代码进行大改,写一个新的微信号注册的实现,然后在原来的代码中修改一下你要注册的账号种类就好了。
实现
工厂模式细分为简单工厂,普通工厂,抽象工厂,看起来很复杂,其实就是你怎么构建这个工厂的问题,如果你只有一个工厂(一个类)一条流水线(一个方法)来创造所有的对象那就是简单工厂:
定义接口:
public interface Account {
public void register();
}
定义可以开通qq账户的工作人员:
public class QQAccount implements Account {
@Override
public void register() {
System.out.println("register qq now……");
}
}
定义可以开通微信账户的工作人员:
public class WechatAccount implements Account {
@Override
public void register() {
System.out.println("register wechat now……");
}
}
定义工厂:
public class SimpleFactory {
public Account getOpenAcctBean(String type) {
if ("qq".equals(type)) {
return new QQAccount();
}else if("wechat".equals(type)){
return new WechatAccount();
}else{
return null;
}
}
}
测试:
public static void main(String[] args) {
SimpleFactory simpleFactory = new SimpleFactory();
simpleFactory.getOpenAcctBean("qq").register();
simpleFactory.getOpenAcctBean("wechat").register();
simpleFactory.getOpenAcctBean("taobao").register();
}
输出结果:
register qq now……
register wechat now……
Exception in thread “main” java.lang.NullPointerException
简单工厂通过一个方法创建所有对象,调用方通过传入一个类型type来告诉工厂创建哪一个对象,我们看到打印结果最后的空指针就知道了问题所在,调用发不能第一时间知道你到底能创建几种对象,如果我想开一个淘宝用户呢,就空指针了,而且如果当你能够开淘宝用户的时候,你不得不去修改你原来的代码,在if else判断中再加一个if else,这破坏了开闭原则,所以普通工厂修改了这一点,通过多条流水线(方法)来创建对象:
public class CommonFactory {
public Account createQQAccount(){
return new QQAccount();
}
public Account createWechatAccount(){
return new WechatAccount();
}
}
测试:
public static void main(String[] args) {
CommonFactory simpleFactory = new CommonFactory();
simpleFactory.createQQAccount().register();
simpleFactory.createWechatAccount().register();
}
结果:
register qq now……
register wechat now……
既然我们可以从一条流水线改到多条,我们也同样可以把一个工厂改成多个工厂,这也就成了所谓的抽象工厂模式,这样做的原因是,当业务不断地扩展,原来的工厂已经很复杂了,如果继续新增或者修改其中的配置不是很容易,这个时候就需要抽象工厂。抽象工厂比普通工厂更加符合开闭原则,并且符合单一职责原则:
定义抽象工厂:
public interface AbstractFactory {
public Account createAccount();
}
构建能创建qq工作人员的工厂
public class QQFactoryImpl implements AbstractFactory{
@Override
public Account createAccount() {
return new QQAccount();
}
}
构建能创建微信工作人员的工厂
public class WechatFactoryImpl implements AbstractFactory {
@Override
public Account createAccount() {
return new WechatAccount();
}
}
测试:
public static void main(String[] args) {
AbstractFactory abstractFactory = new WechatFactoryImpl();
abstractFactory.createAccount().register();
AbstractFactory abstractFactory1 = new QQFactoryImpl();
abstractFactory1.createAccount().register();
}
结果:
register wechat now……
register qq now……
如果说工厂模式哪里有应用的话,那spring的IOC可以说是把工厂模式表达的淋漓至尽,从此我们不在需要在spring中手动去new一个业务对象,只需要加上一个注入的注解,spring自动帮我们去创建和获取对象,拿上面这个账户注册举例,当我们需要新创造一个开微信账户的类时,我们只需要重新写一个新的类,并在上面加上注入注解,然后在需要使用的地方也加上注解,就能完美解决这么一个新增功能的开发,不需要我们去破坏原本业务中的任何一行代码。