设计模式(六)——抽象工厂模式
感冒了几天,没写。今天继续,上次写到工厂方法模式了,总的来说,工厂方法模式还是挺简单的,这次讲的抽象工厂模式,听名字也知道应该是与工厂模式是一脉相承的,顾名思义就是将工厂模式抽象化了,是的,木有错,就是这样,实质上就是在具体产品和具体实现工厂与各自接口中间再加入了一个抽象类,这样做有什么好处?废话,没好处我闲的那什么疼要多加一层?现在不说,写完一看就知道,然后这里引入两个专业概念:产品等级,产品族。其实很好理解,先记着,用到的时候讲。
我们接着上一讲的例子,仍然是老板要造汽车,现在的情况是,老板有间汽车工厂,可以造奥迪和奔驰车,但是老板想,奥迪和奔驰有各种不同型号的车嘛,是的,那。。。我也不是卖车的,也没买过奥迪和奔驰,我也不知道有哪些型号,呵呵,嗯,早知道我应该举个造电脑的例子我可能熟悉点,不管了,我就假设奥迪的车都分为两种,一种普通的车,一种特殊型号的车,特殊用途的,具体什么特殊用途你自己想象。同样奔驰车也大体归为这两大类。
那我们首先还是定义一个所有车的接口,不过这次我们加个型号:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:Car <br/>
* Function: 定义一个汽车的公共接口. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:04:52 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public interface Car {
/**
* run:车都可以跑. <br/>
* @author gongyong
* @since JDK 1.6
*/
public void run();
/**
* style:车都有个型号. <br/>
* @author gongyong
* @since JDK 1.6
*/
public void style();
}
然后,我们定义一个抽象的汽车类来实现这个公共的汽车接口,这里有个有意思的地方,就是面试的时候经常会被问到的一个问题,面试官问你,抽象类如果实现了某个接口是不是一定要实现该接口的所有方法?你说呢,呵呵,往下看:
抽象的奥迪汽车类:
package com.gy.designpattern.abstractfactory;
/**
* ClassName: AudiCar <br/>
* Function: 奥迪车的抽象类. <br/>
* Reason: TODO ADD REASON(可选). <br/>
* date: 2012-7-6 下午3:02:14 <br/>
*
* @author gongyong
* @version
* @since JDK 1.6
*/
public abstract class AudiCar implements Car{
/**
*奥迪可以跑.
* @see com.gy.designpattern.factorymethod.Car#run()
*/
@Override
public void run(){
System.out.println("奥迪在跑!");
}
}
抽象的奔驰车类:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:BenzCar <br/>
* Function: 奔驰汽车抽象模型 <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-4 下午2:09:00 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public abstract class BenzCar implements Car{
/**
* 奔驰可以跑.
* @see com.gy.designpattern.factorymethod.Car#run()
*/
@Override
public void run(){
System.out.println("奔驰在跑!");
}
}
先把所有的汽车的具体实现都写完再写工厂类吧,下面是具体的汽车类:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:NormalAudiCar <br/>
* Function: 这是正常型号的奥迪车的具体类. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:39:25 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class NormalAudiCar extends AudiCar{
/**
* 定义汽车的型号.
* @see com.gy.designpattern.abstractfactory.Car#style()
*/
@Override
public void style(){
System.out.println("这是正常型号的奥迪车");
}
}
package com.gy.designpattern.abstractfactory;
/**
* ClassName:NormalBenzCar <br/>
* Function: 普通型号的奔驰车. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:42:50 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class NormalBenzCar extends BenzCar{
/**
* 定义汽车的型号
* @see com.gy.designpattern.abstractfactory.Car#style()
*/
@Override
public void style(){
System.out.println("这是正常型号的奔驰车");
}
}
package com.gy.designpattern.abstractfactory;
/**
* ClassName:SpecialAudiCar <br/>
* Function: 特殊型号的奥迪车. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:41:22 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class SpecialAudiCar extends AudiCar{
/**
* 特殊型号的奥迪车.
* @see com.gy.designpattern.abstractfactory.Car#style()
*/
@Override
public void style(){
System.out.println("这是特殊型号的奥迪车");
}
}
package com.gy.designpattern.abstractfactory;
/**
* ClassName:SpecialAudiCar <br/>
* Function: 特殊型号的奔驰车. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:41:22 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class SpecialBenzCar extends BenzCar{
/**
* 特殊型号的奔驰车.
* @see com.gy.designpattern.abstractfactory.Car#style()
*/
@Override
public void style(){
System.out.println("这是特殊型号的奔驰车");
}
}
好了,讲到这里,所有的具体的汽车类都实现了,还记得前面讲到的两个专业术语吧,产品等级和产品族,不拽文了,前面的两个抽象的汽车类就叫产品等级,继承了这两个抽象类的具体的汽车类就叫产品族,that's it,就这样,不是我非要拽这俩词,是很多写的很专业的设计模式的书里老提这俩词,显得很高端,其实,你懂的。。。go on
然后我们来看工厂类:
我们也先定义下工厂的接口,注意了,这里和工厂方法模式不一样了,工厂方法模式里是直接写了一个具体的工厂类,而我们这里先写个接口,然后再写一个抽象的工厂类实现该接口,如下:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:CarFactory <br/>
* Function: 汽车工厂接口. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:06:15 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public interface CarFactory {
/**
* createAudiCar:创建奥迪车的工厂. <br/>
* @author gongyong
* @return
* @since JDK 1.6
*/
public Car createAudiCar();
/**
* createBenzCar:创建奔驰车的工厂. <br/>
* @author gongyong
* @return
* @since JDK 1.6
*/
public Car createBenzCar();
}
抽象的工厂类:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:AbstractCarFactory <br/>
* Function: 抽象的工厂类. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:08:44 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public abstract class AbstractCarFactory implements CarFactory{
/**
* createCar:根据枚举类型创建汽车. <br/>
* @author gongyong
* @param carEnum
* @return
* @since JDK 1.6
*/
protected Car createCar(CarEnum carEnum){
Car car = null;
if(!(carEnum.getValue().equals(""))){
try{
//产生实例
car=(Car)Class.forName(carEnum.getValue()).newInstance();
}catch(Exception e){
e.printStackTrace();
}
}
return car;
}
}
注意,这里我用到枚举这个东东,其实完全可以不用,我只是最近看到了就想试试而已,学以致用嘛,稍后贴出这个枚举的的代码,这里不跑题,然后我们写两个具体的工厂类,一个是专门生产普通型号的车的,一个是生产特殊型号的:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:AudiCarFactory <br/>
* Function: 生产普通型号的汽车的工厂. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:23:37 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class NormalCarFactory extends AbstractCarFactory{
/**
* 创建正常型号奥迪车.
* @see com.gy.designpattern.abstractfactory.CarFactory#createAudiCar()
*/
@Override
public Car createAudiCar(){
return super.createCar(CarEnum.AudiNormalCar);
}
/**
* 创建正常型号奔驰车.
* @see com.gy.designpattern.abstractfactory.CarFactory#createBenzCar()
*/
@Override
public Car createBenzCar(){
return super.createCar(CarEnum.BenzNormalCar);
}
}
package com.gy.designpattern.abstractfactory;
/**
* ClassName:SpecialCarFactory <br/>
* Function: 制造特别型号的汽车工厂. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:36:37 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class SpecialCarFactory extends AbstractCarFactory{
/**
* 制造特别型号的奥迪车.
* @see com.gy.designpattern.abstractfactory.CarFactory#createAudiCar()
*/
@Override
public Car createAudiCar(){
// TODO Auto-generated method stub
return super.createCar(CarEnum.AudiSpecialCar);
}
/**
* 制造特别型号的奔驰车.
* @see com.gy.designpattern.abstractfactory.CarFactory#createBenzCar()
*/
@Override
public Car createBenzCar(){
// TODO Auto-generated method stub
return super.createCar(CarEnum.BenzSpecialCar);
}
}
好了,主流程走完了,把枚举也贴上:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:CarEnum <br/>
* Function: 这是个汽车类型的枚举. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-6 下午3:11:28 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public enum CarEnum {
AudiNormalCar("com.gy.designpattern.abstractfactory.NormalAudiCar"),
AudiSpecialCar("com.gy.designpattern.abstractfactory.SpecialAudiCar"),
BenzNormalCar("com.gy.designpattern.abstractfactory.NormalBenzCar"),
BenzSpecialCar("com.gy.designpattern.abstractfactory.SpecialBenzCar");
private String value="";
private CarEnum(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
}
好了,boss登场,开始造车:
package com.gy.designpattern.abstractfactory;
/**
* ClassName:Boss <br/>
* Function: Boss决定要造什么车就造什么. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2012-7-9 下午1:26:18 <br/>
* @author gongyong
* @version
* @since JDK 1.6
* @see
*/
public class Boss {
public static void main(String[] args){
CarFactory normalCarFactory=new NormalCarFactory();
CarFactory specialCarFactory=new SpecialCarFactory();
//生产正常车型的汽车
Car normalAudiCar=normalCarFactory.createAudiCar();
Car normalBenzCar=normalCarFactory.createBenzCar();
//生产特殊车型的汽车
Car specailAudiCar=specialCarFactory.createAudiCar();
Car specailBenzCar=specialCarFactory.createBenzCar();
normalAudiCar.style();
normalAudiCar.run();
normalBenzCar.style();
normalBenzCar.run();
specailAudiCar.style();
specailAudiCar.run();
specailBenzCar.style();
specailBenzCar.run();
}
}
呼~~我勒个去~终于写完了,好长啊,我都忍不住说一句,抽象工厂方法好麻烦啊,好,回答前面的问题,这个模式这么麻烦,到底有什么好处:是这样的,非常重要的有点就是,工厂模式符合OCP 原则,也就是开闭原则,怎么说呢,比如就车的型号的问题,还有很多其他用途的奔驰车和奥迪车,比如用来飞的,那这个就是要在我们的产品族中增加一类产品,同时再增加一个工厂就可以解决这个问题;还有一个非常大的有点,高内聚,低耦合,在一个较大的项目组,产品是由一批人定义开发的,但是提供其他成员访问的时候,只要提供工厂方法和产品的接口,也就是说只需要提供Product Interface 和抽象工厂,当然也可以提供具体工厂实现,根据实际情况来吧, 就可以产生自己需要的对象和方法。可扩展性很高,当然还有其他优点,自己可以总结,我目前就想到这些了。
分享到:
相关推荐
抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体的类。这种模式允许客户端使用一个通用接口来创建一组相关或相互依赖的对象,而无需关心它们的具体实现。在Java或其他...
抽象工厂模式是设计模式中的一种创建型模式,它提供了一种创建对象集合的接口,而无需指定具体类。这种模式的主要目的是为了隔离产品对象的创建和使用,使得系统对产品类的依赖降低到最低,同时也方便了产品的扩展和...
抽象工厂模式是一种重要的软件设计模式,它属于创建型模式,主要解决的是当系统需要创建一系列相关或相互依赖的对象时,而这些对象的类在运行时可能不确定的问题。在这个模式中,我们通过一个抽象工厂接口来定义创建...
Android之大话设计模式——:抽象工厂模式借鉴.pdf
Android之大话设计模式——:抽象工厂模式参考.pdf
抽象工厂模式是一种设计模式,属于创建型模式,它提供了一种创建对象集合的方式,这些对象来自相关联的产品家族,而且每个对象都属于不同的抽象产品类。在“格斗类游戏软件”的场景中,这个模式可以帮助我们根据玩家...
抽象工厂模式则更进一步,它提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们的具体类。在多线程或者跨平台的C#应用中,抽象工厂可以帮助我们隔离产品族,使得更换产品族变得容易。例如,我们可以有...
根据应用场景的不同,工厂模式可以进一步分为简单工厂模式、工厂方法模式以及抽象工厂模式。 #### 二、简单工厂模式 简单工厂模式是最基础的工厂模式实现方式,它的主要特点是使用一个工厂类来负责创建所有产品...
今天我们将深入探讨“抽象工厂模式”(Abstract Factory Pattern),它在“深入浅出设计模式四——多区域比萨加盟店生产比萨实现”中得到了应用。这个模式主要用于创建一系列相关的对象,而无需指定其具体的类。 ...
**设计模式——简单工厂模式** 简单工厂模式是创建型设计模式的一种,它提供了一种创建对象的最佳方式。在简单工厂模式中,一个专门的类(称为工厂类)负责创建对象,客户端无需知道所创建的对象的具体类,只需要...
本文将探讨三个重要的设计模式:抽象工厂模式、工厂方法模式以及策略模式,并结合一个实际的场景——手机加工厂,来具体阐述它们的应用。 首先,我们来看**抽象工厂模式**。这个模式主要用于创建相关或依赖对象的...
通过更换模具,同一台设备可以快速切换生产不同车型的零件,这就是抽象工厂模式的核心思想——封装变化。 在虚拟案例中,我们有一个名为Softo的软件系统,用于计算员工的工资。在中国,员工工资的计算规则是固定的...
工厂方法模式是面向对象设计模式中的一种,它属于创建型模式,主要解决的是当系统需要创建的对象具有多种类型,而具体创建哪种类型的对象在运行时才能确定的问题。在这个压缩包中,`FactoryMethod`可能包含了Java...
工厂模式和抽象工厂模式是两种常用的创建型设计模式,它们都与对象的创建有关,但各有侧重。本篇文章将详细阐述这两种模式的核心概念、应用场景以及它们在实际编程中的应用。 首先,我们来看工厂模式。工厂模式是一...
工厂方法模式则更进一步,它属于抽象工厂模式的一种特殊形式。在这个模式中,我们定义一个创建对象的接口,但让子类决定实例化哪一个类。工厂方法将类的实例化推迟到子类。这样,工厂方法模式使得系统在不指定具体...
**设计模式——抽象工厂之小解** 在软件工程中,设计模式是一种被广泛采用的解决常见问题的经验总结,它们是经过验证的、可重用的解决方案。抽象工厂(Abstract Factory)设计模式是其中的一种创建型模式,它提供了...
在《设计模式实现——观察者模式》这篇博客中,作者可能详细解释了观察者模式的概念、结构以及其在实际编程中的应用。以下是对观察者模式的详细阐述: 1. **模式定义**:观察者模式是一种对象行为型模式,它允许...
**Java设计模式——抽象工厂** 在软件工程中,设计模式是一种在特定场景下解决常见问题的模板或蓝图。抽象工厂模式是设计模式中的一种结构型模式,它提供了一个创建对象族的接口,但允许子类决定实例化哪一个类。这...
抽象工厂模式提供了一个接口,用于创建相关或依赖对象的家族,而不必指定它们的具体类。 在抽象工厂模式中,有以下几个关键角色: 1. **抽象工厂(Abstract Factory)**:这是工厂模式的核心接口,定义了创建产品...
本文实例讲述了Python设计模式之抽象工厂模式原理与用法。...设计模式——抽象工厂模式 抽象工厂模式(Abstract Factory Pattern):提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类 import sys #抽