前言
工厂模式在项目中被广泛的使用。使用设计模式,可以让很复杂的业务用简单的代码表达出来。
工厂模式的概述
首先我们举个栗子来说明,在相传的神话中,最早的一批人类是通过女娲造人来产生的,女娲就是一个客户端的调用方,也是场景的执行者。黄色人种,白色人种,黑色人种就是要产生的产品。即工厂中的产品。
我们再来定义一个抽象工厂用来生成产品。示意代码如下所示:
1 public abstract classAbstractHumanFactory {2
3 public abstract T createHuman(Classc);4 }
其中入参是人类的类型,出参是对应的人类。接下来我们来定义一下具体的人类。首先新增一个人类的抽象接口以及具体的三种肤色的人类,如下代码示意:
1 public interfaceHuman {2
3 public voidgetColor();4
5 public voidtalk();6 }
1 public class BlackHuman implementsHuman {2 @Override3 public voidgetColor() {4
5 System.out.println("我是黑人");6
7 }8
9 @Override10 public voidtalk() {11 System.out.println("黑人会说话");12 }13 }
1 public class WhiteHuman implementsHuman {2 @Override3 public voidgetColor() {4 System.out.println("我是白人");5
6 }7
8 @Override9 public voidtalk() {10 System.out.println("白人会说话");11
12 }13 }
public class YellowHuman implementsHuman {
@Overridepublic voidgetColor() {
System.out.println("我是黄人");
}
@Overridepublic voidtalk() {
System.out.println("黄人会说话");
}
}
最后我们新增一个抽象工程的具体工厂方法。如下代码所示:
1 public class HumanFactory extendsAbstractHumanFactory {2 @Override3 public T createHuman(Classc) {4 Human human = null;5 try{6 human =(T)Class.forName(c.getName()).newInstance();7 } catch(Exception e) {8
9 }10 return(T)human;11 }12 }
最后我们新增一个场景类Client:
public classClient {public static voidmain(String[] args) {
AbstractHumanFactory humanFactory= newHumanFactory();
BlackHuman blackHuman= humanFactory.createHuman(BlackHuman.class);
blackHuman.getColor();
blackHuman.talk();
WhiteHuman whiteHuman= humanFactory.createHuman(WhiteHuman.class);
blackHuman.getColor();
blackHuman.talk();
YellowHuman yellowHuman= humanFactory.createHuman(YellowHuman.class);
yellowHuman.getColor();
yellowHuman.talk();
}
}
运行结果如下所示:
我是黑人
黑人会说话
我是黑人
黑人会说话
我是黄人
黄人会说话
工厂模式的定义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使得一个类的实例化延迟到子类。
总结一下,在工程模式中,我们拥有客户端,也就是调用方。同时拥有工厂接口和具体的工厂实现。另外还包含产品接口和具体产品。
1.采用工厂模式,只要客户端知道要产生什么产品整套链路就确认下来了,无须知晓产品产生的细节。这降低了模块之间的耦合。
2.当增加一个产品,只需要实现产品接口即可,工厂类不需要任何的变动。这符合设计原则中的开闭的原则。对修改关闭,对扩展开放。
最后我们再来总结一下工厂模式的通用实现方式:
①首先我们需要有抽象产品类,同时拥有公共的方法prepare();以及抽象的处理方法handle();
1 packagecom.example.pattern.factory.summary;2
3 public abstract classAbstractProduct {4
5 public voidprepare() {6
7 }8
9
10 public abstract voidhandle();11 }
②需要有具体的产品类,这些产品类继承了抽象产品类,重写的handle抽象方法。
1 packagecom.example.pattern.factory.summary;2
3 public class ConcreteProductFirst extendsAbstractProduct {4
5
6 @Override7 public voidhandle() {8
9 }10 }
这样的产品类可以有多个,主要用来负责产品的产生,但是要保证这个产品是一个具体的产品。
③抽象工厂类
1 packagecom.example.pattern.factory.summary;2
3 public interfaceIFactory {4
5 public T createProduct(Classclazz) ;6
7 }
抽象工厂类可以定义为接口,也可以定义为抽象类。在实际中可以采用定义一个接口,一个抽象类实现这个接口,把公共的实现方法抽取到抽象类中实现,具体的工厂类再去继承这个抽象工厂。
④具体工厂类
1 packagecom.example.pattern.factory.summary;2
3 public class ConcreteFactory implementsIFactory {4 @Override5 public T createProduct(Classclazz) {6
7 AbstractProduct product = null;8
9 try{10 product =(AbstractProduct)Class.forName(clazz.getName()).newInstance();11 } catch(Exception e) {12
13 }14
15 return(T)product;16 }17 }
⑤业务场景类
1 packagecom.example.pattern.factory.summary;2
3 public classClient {4
5 public static voidmain(String[] args) {6 IFactory factory = newConcreteFactory();7
8 ConcreteProductFirst product = factory.createProduct(ConcreteProductFirst.class);9 product.handle();10
11 }12 }
以上代码是工厂模式的通用写法,在实际应用中可以适当调整,或者和其他的设计模式混合使用。