在前篇模式设计的文章中,我们讲述了一下工厂设计模式的原理,在这篇文章中,我们再引入另一个设计模式-----抽象工厂模式,来对比一下两者之间的差别。
在开始这篇文章之前,我们先扯点闲话放松放松。某一天,我正在家打游戏,打的正high呢,突然小乔跑过来跟我语重心长的跟我说:XX同志,我有一件
很重要的事要跟你商量一下,关系到我的生命安全。我一听这么严重,赶忙扔掉游戏问怎么回事,.........(此处省略一万字)原来是这几天做公交上班,每次都迟到
被老板批评了,然后跟我商量能不能买个小车开开,我一想确实应该买个车了,于是两人一拍即合直奔SSSS店。当然啦,小女生么都喜欢ABB的车,所以一到
购车广场就拉着我逛了AUDI,BMW,BENZ等4S店。车不仅具有不同的品牌,还有不同的用途分类,如跑车,SUV,小乔就比较喜欢跑车,而我就比较喜欢后者,
至于买了什么车在这里不重要,这个例子主要是为了引出我们今天所要讲的设计模式。
BMW的跑车有Z4,M系列,X系列的车型属于SUV,我们用设计模式分别实现车辆的生产过程。我们来看一下类图:
在类图中,产品类很简单,我们从品牌跟车型两个角度去看,每个品牌下面都有两个车型,跑车和SUV,同时我们又建了两个工厂,一个生产宝马车,一个生产奔驰车。
该类图的代码如下所示:
package com.org;
/*
* @brief 汽车接口
* */
public interface ICar {
public String getBand();
public String getModel();
}
package com.org;
/*
* @brief 抽象宝马车
* */
public abstract class AbsBMW implements ICar{
private final static String BMW_BAND = "宝马汽车";
public String getBand(){
return BMW_BAND;
}
/*
* @brief 型号由具体实现类实现
* */
public abstract String getModel();
}
package com.org;
/*
* @brief 宝马SUV
* */
public class BMWSuv extends AbsBMW{
private final static String BMW_SUV = "宝马SUV";
@Override
public String getModel() {
// TODO Auto-generated method stub
return BMW_SUV;
}
}
package com.org;
/*
* @brief 宝马包车
* */
public class BMWSports extends AbsBMW{
private final static String BMW_SPORTS = "宝马跑车";
@Override
public String getModel() {
// TODO Auto-generated method stub
return BMW_SPORTS;
}
}
package com.org;
/*
* @brief 抽象奔驰车
* */
public abstract class AbsBENZ implements ICar{
private final static String BENZ_BAND = "奔驰汽车";
public String getBand(){
return BENZ_BAND;
}
/*
* @brief 具体型号由实现类决定
* */
public abstract String getModel();
}
package com.org;
/*
* @brief 奔驰SUV
* */
public class BENZSuv extends AbsBENZ{
private final static String BENZ_SUV = "奔驰G系列";
@Override
public String getModel() {
// TODO Auto-generated method stub
return BENZ_SUV;
}
}
package com.org;
/*
* @brief 奔驰跑车
* */
public class BENZSports extends AbsBENZ{
private final static String BENZ_SPOIRT = "奔驰包车";
@Override
public String getModel() {
// TODO Auto-generated method stub
return BENZ_SPOIRT;
}
}
package com.org;
/*
* @brief 抽象工厂
* */
public interface CarFactory {
//生产suv
public ICar createSuv();
//生产跑车
public ICar createSport();
}
package com.org;
/*
* @brief 宝马车工厂
* */
public class BMWFactory implements CarFactory{
@Override
public ICar createSuv() {
// TODO Auto-generated method stub
return new BMWSuv();
}
@Override
public ICar createSport() {
// TODO Auto-generated method stub
return new BMWSports();
}
}
package com.org;
/*
* @brief 奔驰车工厂
* */
public class BENZFactory implements CarFactory{
@Override
public ICar createSuv() {
// TODO Auto-generated method stub
return new BENZSuv();
}
@Override
public ICar createSport() {
// TODO Auto-generated method stub
return new BENZSports();
}
}
package com.org;
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//生产汽车....
System.out.println("生产一辆BMW SUV");
System.out.println("1.找到生产BMW的工厂");
CarFactory carFactory = new BMWFactory();
System.out.println("2.开始生产BMW SUV");
ICar benzSuv = carFactory.createSuv();
System.out.println("3.生产信息如下");
System.out.println("汽车品牌:" + benzSuv.getBand());
System.out.println("汽车型号:" + benzSuv.getModel());
}
}
运行结果如下:
以上就是这个例子的全部代码,抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种,业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
他的优点在于有非常好的封装性,用户不需要知道对象时如何创建出来的,只要知道工厂类是谁,就可以创建出一个需要的对象。而且产品内部的约束为非公开状态。
他最大的缺点就在于产品族扩展非常困难,举个例子来说,如果我们要增加一个奥迪车的产品,我们的类图是不是要改动很多地方,违反了开闭原则。
工厂模式与抽象工厂模式的不同:
在工厂方法模式里,我们关注的是一个产品整体,一般都是单一性质的产品,而抽象工厂模式实现的是对产品家族的创建,一个产品家族是具有不同分类维度的产品组合。