标签:
工厂模式是一种创建者模式,在任何生成复杂对象的地方都可以使用工厂模式。理论来说在任何使用A a = new A()的方式都可以使用工厂模式,虽然使用工厂模式可能需要多做一些工作,但是在后续的开发和维护都带来了方便。
如果我们需要在构建对象的时候,需要做很多的处理工作,比如初始化工作,查询工作等一些耗时的工作,如果我们将这些操作全部放入到构造方法中去写,那么势必在后期维护的带来不方便,而且始化工作如果是很长一段代码,说明要做的工作很多,将很多工作装入一个方法中,相当于将很多鸡蛋放在一个篮子里,是很危险的,这也是有悖于Java面向对象的原则,面向对象的封装(Encapsulation)和分派(Delegation)告诉我们,尽量将长的代码分派“切割”成每段,将每段再“封装”起来(减少段和段之间耦合联系性),这样,就会将风险分散,以后如果需要修改,只要更改每段,不会再发生牵一动百的事情。
抽象工厂模式
三者之间的区别:
简单工厂模式,一个具体工厂类负责生产所有的具体产品。客户端只需要关注生成的具体产品。
- Factory : 负责生产具体的产品工厂
- Product: 抽象的产品类,
- P1: 具体的产品类P1
- P2: 具体的产品类P2
汽车工厂造汽车的例子。首先Rrtoyewx在大众厂里面上班,一开始被分配到了上海大众里面去了,只管Passat和polo两款车型,而且做的事很简单,就是简单开出去测试一下车子的性能。这个时候事务较少,Rrtoyewx觉得用简单工厂就能搞定了。
package图如下:
- Volkswagen:抽象的大众汽车类
- Passat,Polo:具体的大众汽车类
- ShangHaiVolkswagenFactory: 上海大众汽车工厂
- Client: 客户端类
产品类
Volkswagen
public interface Volkswagen {
void drive();
String getName();
}
Passat
public class Passat implements Volkswagen {
public static final int ID = 0;
@Override
public void drive() {
System.out.println("Passat开出去咯,测试成功");
}
@Override
public String getName() {
return "Passat";
}
}
Polo
public class Polo implements Volkswagen{
public static final int ID = 1;
@Override
public void drive() {
System.out.println("Polo开出去咯,测试成功");
}
@Override
public String getName() {
return "Polo";
}
}
工厂类
public class ShangHaiVolkswagenFactory {
public Volkswagen createVolkswagen(int id){
Volkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
客户端类
public class Client {
public static void main(String[] args) {
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
Volkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
Volkswagen polo = factory.createVolkswagen(Polo.ID);
System.out.println(polo.getName());
}
}
打印出的log为
每次测试的时候Client类都跑了一遍,似乎很简单,同样的也方便以后的扩展(添加新的车型的时候),只需要添加一个产品类,然后在工厂里添加响应的逻辑就行了。Rrtoyewx觉得自己这个测试车辆程序完全够用了。
注意对于上面的工厂,可以采用反射的形式去创建产品类,如下面的代码
public class ShangHaiVolkswagenFactory {
//产品的id
public Volkswagen createVolkswagen(int id){
Volkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
//反射得到
public Volkswagen createVolkswagen(Class <? extends Volkswagen> clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
}
}
优点:客户端需要的什么产品,可以直接得到,逻辑判断在工厂里面,
缺点:扩展性一般,产品都是一个产品族下面的产品,对于不在产品族中的产品,没办法去扩展,另外获得具体某种产品的逻辑放在工厂里面,新添加产品的时候就需要修改工厂里面的代码。
- AbstractProduct:抽象的产品类
- ProductA:具体的A产品
- ProductB:具体的B产品
- AbstractFactory:抽象工厂类
- FactoryA:具体的生产A产品的工厂类
- FactoryB:具体的生产B产品的工厂类
- Client: 客户端类
还是上面的栗子的。Rrtoyewx在负责上海大众的两款车型,本来就着简单工厂的模式测试车辆的时候,日子过的非常好,可是好景不长,突然有一天领导说Rrtoyewx说:一汽大众厂最近较忙,看你比较清闲,你就顺便把一汽大众的迈腾,和速腾都测一下。本来Rrtoyewx觉得挺简单的,就是简单再添加一个Magotan和Sagitar,然后通过工厂生成就行了,可是等Rrtoyewx一拿到测试的项目的时候,发现并不是只测试drive,Sagitar和Magotan不仅需要测试drive,而且需要测试brake。好吧,Rrtoyewx觉得以前写的都不能够用了。想了很久,Rrtoyewx 觉得需要将简单工厂模式升级到工厂模式,关注点也发生了改变不再为具体的车辆的,而是一汽大众的车(Magotan和Sagitar)还是上海大众的车(Passat和 Polo)了
修改过后的package图:
- Volkswagen: 抽象的汽车类
- ShangHaiVolkswagen:上海大众汽车的抽象类
- FAWVolkswagen:一汽大众汽车的抽象类
- Passat,Polo:上海大众厂汽车类的具体类
- Magotan,Sagitar:一汽大众厂汽车的具体类
- VolkswagenFactory:抽象的大众汽车工厂
- ShangHaiVolkswagenFactory:上海大众汽车工厂,主要负责测试Passat和Polo
- FAWVolkswagenFactory:一汽大众的工厂,主要负责测试Magotan和Sagitar
Volkswagen类,将Volkswagen类转成抽象类
public abstract class Volkswagen {
public abstract void drive();
public abstract String getName();
}
ShangHaiVolkswagen:上海大众汽车的抽象类
public abstract class ShangHaiVolkswagen implements Volkswagen{
}
FAWVolkswagen : 一汽大众汽车的抽象类,多了一个brake()的方法
public abstract class FAWVolkswagen implements Volkswagen {
public abstract void brake();
}
VolkswagenFactory : 汽车工厂的抽象类,并将createVolkswagen(Class clazz)声明称final类型。供子类使用
public abstract class VolkswagenFactory {
public abstract Volkswagen createVolkswagen(int productID);
public final Volkswagen createVolkswagen(Class <? extends Volkswagen> clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
};
}
上海大众的具体实现类
Passat类
public class Passat extends ShangHaiVolkswagen {
public static final int ID = 0;
@Override
public void drive() {
System.out.println("Passat开出去咯,测试成功");
}
@Override
public String getName() {
return "Passat";
}
}
Polo类
public class Polo extends ShangHaiVolkswagen{
public static final int ID = 1;
@Override
public void drive() {
System.out.println("Polo开出去咯,测试成功");
}
@Override
public String getName() {
return "Polo";
}
}
一汽大众的汽车类。
Sagitar类,
public class Sagitar extends FAWVolkswagen {
public static final int ID = 2;
@Override
public void drive() {
System.out.println("Sagitar 开出去了,测试成功了");
}
@Override
public String getName() {
return "Sagitar";
}
@Override
public void brake(){
System.out.println("Sagitar 刹车挺好的,测试通过了");
}
}
Magotan 类
public class Magotan extends FAWVolkswagen{
public static final int ID = 3;
@Override
public void drive() {
System.out.println("Magotan 开出去咯,测试成功了");
}
@Override
public String getName() {
return "Magotan";
}
@Override
public void brake(){
System.out.println("Magotan 刹车挺好的,测试通过");
}
}
注意重载方法的返回类型已经修改称对应的产品类,不在是Volkswagen类型了
ShangHaiVolkswagenFactory:负责生产上海汽车的工厂类
public class ShangHaiVolkswagenFactory extends VolkswagenFactory {
public ShangHaiVolkswagen createVolkswagen(int id){
ShangHaiVolkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
FAWVolkswagenFactory:负责生产一汽汽车的工厂类
public class FAWVolkswagenFactory extends VolkswagenFactory {
@Override
public FAWVolkswagen createVolkswagen(int productID) {
FAWVolkswagen volkswagen = null;
switch(productID){
case Magotan.ID:
volkswagen = new Magotan();
break;
case Sagitar.ID:
volkswagen = new Sagitar();
break;
default:
volkswagen = null;
}
return volkswagen;
}
}
Client类:用来测试
public class Client {
public static void main(String[] args) {
System.out.println("开始测试上海大众的车辆");
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
polo.drive();
System.out.println("开始测试一汽大众的车辆");
FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();
FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
magotan.drive();
magotan.brake();
FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
sagitar.drive();
sagitar.brake();
}
}
打印log的也能够正确的测试:
通过下面的改变,Rrtoyewx将工厂抽象出生产上海大众的车子和一汽大众的车子的两个工厂,并将一汽大众和上海大众的车子做了区分,形成两个不同产品族的产品系列。并由两个工厂分别对应去生产。等Rrtoyewx做完了这么多后,终于发现原先的系统还是有漏洞的,还是有局限性的,好在及时的弥补。Rrtoyewx发现现有的系统无论处理一汽大众的车子还是上海大众的车子,甚至于再加一个进口大众工厂的车子也够用了。再以后的扩展也能得到了提升了。
优点:扩展性,能够处理不同产品系列的产品,通过具体的工厂去生成不同产品族的产品,扩展性较好。
缺点:类的个数较多。另外一个工厂的只能够生产一个具体的产品。
- AbstractFactory:抽象工厂类
- ConcreteFactoryA:具体工厂A,负责生产A和B的
- ConcreteFactoryB:具体工厂b,负责生产A和B的
- AbstractProductA,AbstractProductB:抽象的产品类
- ConcreteProductA1,ConcreteProductA2:具体产品A
- ConcreteProductB1,ConcreteProductB1:具体产品B
- Client:客户端
Rrtoyewx在做完上面测试工作之后,上面领导觉得Rrtoyewx工作很不错,想将Rrtoyewx逐渐管理业务层的事(与人打交道),将Rrtoyewx升级了部门经理,同样责任也多了起来了,Rrtoyewx不仅测试原先一些东西,而且需要做一个额外的事情,比如说保险之类。Rrtoyewx在查阅的保险的相关的书籍发现,一汽大众的工厂需要一等保险,而上海大众的车子需要二等保险。 Rrtoyewx 这个时候发现的保险和车子不属于同一个产品。为了处理事务方便Rrotowx需要将原先的系统给升级一下。
升级后的系统的package图
新加了几个类
Insurance:保险的抽象类
OneLevelInsurance:一等保险的实现类
TwoLevelInsurance:二等保险的实现类
Insurance类
public abstract class Insurance {
public abstract String getName();
}
OneLevelInsurance类
public class OneLevellnsurance extends Insurance{
@Override
public String getName() {
return "一级保险";
}
}
TwoLevelInsurance类
public class TwoLevelInsurance extends Insurance {
@Override
public String getName() {
return "二级保险";
}
}
同时修改ShangHaiVolkswagenFactory和FAWVolkswagenFactory以及VolkswagenFactory的代码
具体如下
VolkswagenFactory 添加一个生成Insurance类的方法
public abstract class VolkswagenFactory {
public abstract Volkswagen createVolkswagen(int productID);
public abstract Insurance bindInsurance();
public final Volkswagen createVolkswagen(Class <? extends Volkswagen> clazz){
Volkswagen volkswagen = null;
try {
volkswagen = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return volkswagen;
};
}
ShangHaiVolkswagenFactory绑定一等保险的对象
public class ShangHaiVolkswagenFactory extends VolkswagenFactory {
public ShangHaiVolkswagen createVolkswagen(int id){
ShangHaiVolkswagen volkswagen = null;
switch(id){
case Passat.ID:
volkswagen = new Passat();
break;
case Polo.ID:
volkswagen = new Polo();
break;
default:
volkswagen = null;
}
return volkswagen;
}
@Override
public Insurance bindInsurance() {
return new OneLevellnsurance();
}
}
FAWVolkswagenFactory类:并定二等保险的对象
public class FAWVolkswagenFactory extends VolkswagenFactory {
@Override
public FAWVolkswagen createVolkswagen(int productID) {
FAWVolkswagen volkswagen = null;
switch(productID){
case Magotan.ID:
volkswagen = new Magotan();
break;
case Sagitar.ID:
volkswagen = new Sagitar();
break;
default:
volkswagen = null;
}
return volkswagen;
}
@Override
public Insurance bindInsurance() {
return new TwoLevelInsurance();
}
}
Client客户端测试的类
public class Client {
public static void main(String[] args) {
System.out.println("开始测试上海大众的车辆");
ShangHaiVolkswagenFactory factory = new ShangHaiVolkswagenFactory();
ShangHaiVolkswagen passat = factory.createVolkswagen(Passat.ID);
passat.drive();
ShangHaiVolkswagen polo = factory.createVolkswagen(Polo.ID);
polo.drive();
Insurance shanghaiInsurance = factory.bindInsurance();
System.out.println(shanghaiInsurance.getName());
System.out.println("开始测试一汽大众的车辆");
FAWVolkswagenFactory fawFactory = new FAWVolkswagenFactory();
FAWVolkswagen magotan = fawFactory.createVolkswagen(Magotan.ID);
magotan.drive();
magotan.brake();
FAWVolkswagen sagitar = fawFactory.createVolkswagen(Sagitar.ID);
sagitar.drive();
sagitar.brake();
Insurance fawInsurance = fawFactory.bindInsurance();
System.out.println(fawInsurance.getName());
}
}
打印log为:
Rrtoyewx 做完这些,发现系统已经很健全了,不在为了测试车辆,只要与车辆相关的事宜的对象,由不同的工厂具体去实现。完成这么多,Rrtoyewx 觉得天特别的蓝,心情特别的舒服。
标签:
原文地址:http://blog.csdn.net/zhi184816/article/details/51348567