在前篇模式设计的文章中,我们讲述了一下工厂设计模式的原理,在这篇文章中,我们再引入另一个设计模式-----抽象工厂模式,来对比一下两者之间的差别。
在开始这篇文章之前,我们先扯点闲话放松放松。某一天,我正在家打游戏,打的正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()); } }运行结果如下:
以上就是这个例子的全部代码,抽象工厂模式是工厂方法模式的升级版本,在有多个业务品种,业务分类时,通过抽象工厂模式产生需要的对象是一种非常好的解决方式。
他的优点在于有非常好的封装性,用户不需要知道对象时如何创建出来的,只要知道工厂类是谁,就可以创建出一个需要的对象。而且产品内部的约束为非公开状态。
他最大的缺点就在于产品族扩展非常困难,举个例子来说,如果我们要增加一个奥迪车的产品,我们的类图是不是要改动很多地方,违反了开闭原则。
工厂模式与抽象工厂模式的不同:
在工厂方法模式里,我们关注的是一个产品整体,一般都是单一性质的产品,而抽象工厂模式实现的是对产品家族的创建,一个产品家族是具有不同分类维度的产品组合。