天天看点

【设计模式十之抽象工厂模式】抽象工厂模式详解细说抽象工厂模式

AbstractFactoryPattern抽象工厂模式模式

  • 细说抽象工厂模式
      • 定义
      • UML
      • 抽象工厂模式场景
        • 场景一
        • 场景二
      • 上代码
        • 代码一
        • 代码二
      • 简单工厂模式,工厂方法模式,抽象工厂模式的区别

细说抽象工厂模式

提示:

博主:章飞 _906285288的博客

博客地址:http://blog.csdn.net/qq_29924041

## 细说抽象工厂模式

定义

在之前的博客中,写过简单工厂模式以及工厂方法模式,可以参考

https://blog.csdn.net/qq_29924041/article/details/59118775

https://blog.csdn.net/qq_29924041/article/details/60145361

这两篇博客

但是在工厂模式的大家族范畴内,还有一个比较难理解的抽象工厂模式,其实这种模式也是在实际生活中抽象出来,其实可以想想,在之前工厂模式中,简单工厂模式是一个工厂去生产不同产品,而在工厂方法模式中,是每一个单一的产品都对应了一个具体的工厂,但是在实际生活中,还有一种场景,就是一个工厂既可以去生产主要的产品,也可以去生产附加的其它产品,也就是从抽象工厂的角度来说,每一个实际的工厂都是可以去生产具体的产品信息,达到一种生产对象多对多的场景

来自百科的具体定义

抽象工厂模式是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。根据里氏替换原则,任何接受父类型的地方,都应当能够接受子类型。因此,实际上系统所需要的,仅仅是类型与这些抽象产品角色相同的一些实例,而不是这些抽象产品的实例。换言之,也就是这些抽象产品的具体子类的实例。工厂类负责创建抽象产品的具体子类的实例

UML

【设计模式十之抽象工厂模式】抽象工厂模式详解细说抽象工厂模式

从图中可以看到,Creator这个抽象工厂类,实际是可以生产两种不同的产品,具体到的ConcreteCreator1,可以生产产品A,也可以生产产品B,从而达到一类工厂去生产某一类产品族的效果

抽象工厂模式场景

场景一

来自设计模式之禅中的案例,女娲造人传说,世界上的人可以根据肤色分为黄种人,白种人,黑人,根据性别又可以分成男性,女性,所以自由搭配下,会有6中具体的人。工厂则可以定位,男性和女性工厂,男性工厂去生产所有是男性的不同人种,而女性工厂则去生产所有是女性的不同人种类型。 因此顶层抽象工厂生成的产品类型其实就是有差异的

场景二

在之前的工厂模式的博客中都是使用小米公司的产品来做案例的,小米有生成手机的工厂,同时也有生成电视的共产,生成手机的工厂可能不需要去生产电视,但是生产手机的工厂可能需要去生产手机的配件,或者手机礼品等等,而生产电视的共产也可能去生产电视的相关配件,电视礼品等等。这也就是一个工厂根据需要去生产不同的产品信息,这实际上都是一个工厂生成不同的产品

上代码

代码一

定义一个抽象的人类

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public interface Human {

	//首先定义什么是人类
	//人是愉快的,会笑的,本来是想用smile表示,想了一下laugh更合适,好长时间没有大笑了;
	public void laugh();
	//人类还会哭,代表痛苦
	public void cry();
	//人类会说话
	public void talk();
	//定义性别
	public void sex();

}
           

定义抽象黑人类型,黑人具体分为男性黑人和女性黑人

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public abstract class AbstractBlackHuman implements Human{
	public void cry() {
		System.out.println("黑色人种会哭");
	}

	public void laugh() {
		System.out.println("黑色人种会大笑,幸福呀!");
	}
	
	public void talk() {
		System.out.println("黑色人种会说话,一般说的都是双字节");
	}
}
           

定义抽象白人类型,白人具体分为男性白人和女性白人

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public abstract class AbstractWhiteHuman implements Human{

	public void cry() {
		System.out.println("白色人种会哭");
	}

	public void laugh() {
		System.out.println("白色人种会大笑,幸福呀!");
	}
	
	public void talk() {
		System.out.println("白色人种会说话,一般说的都是双字节");
	}
}

           

定义抽象黄种人类型,黄钟人具体分为男性黄种人和女性黄种人

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

/**
 * 为什么要修改成抽象类呢?要定义性别呀
 * @author zhangfei.zhou
 *
 */
public abstract class AbstractYellowHuman implements Human{
	
		public void cry() {
			System.out.println("黄色人种会哭");
		}

		public void laugh() {
			System.out.println("黄色人种会大笑,幸福呀!");
		}
		
		public void talk() {
			System.out.println("黄色人种会说话,一般说的都是双字节");
		}
	

}

           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class BlackFemaleHuman extends AbstractBlackHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该黑种人的性别为女...");
	}

}
           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class BlackMaleHuman extends AbstractBlackHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该黑种人的性别为男...");
	}

}
           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class WhiteFemaleHuman extends AbstractWhiteHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该白种人的性别为女...");
	}

}

           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class WhiteMaleHuman extends AbstractWhiteHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该白种人的性别为男...");
	}

}

           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class YellowFemaleHuman extends AbstractYellowHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该黄种人的性别为女...");
	}

}

           
package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class YellowMaleHuman extends AbstractYellowHuman{

	@Override
	public void sex() {
		// TODO Auto-generated method stub
		System.out.println("该黄种人的性别为男...");
	}

}

           

定义顶层的工厂,用于去生产黄种人,白种人,黑人

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public interface HumanFactory {
	//制造黄色人种
	public Human createYellowHuman();
	//制造一个白色人种
	public Human createWhiteHuman();
	//制造一个黑色人种
	public Human createBlackHuman();
}

           

抽象工厂类型,主要是定义清楚创建方法

package src.com.zzf.designpattern.abstractfactorypattern.demo2;
public abstract class AbstractHumanFactory implements HumanFactory{
	protected Human createHuman(Class<? extends Human> humanEnumClass){
		
		try {
			return humanEnumClass.newInstance();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
		
	}
}

           

生产女性的工厂

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class FemaleHumanFactory extends AbstractHumanFactory{

	@Override
	public Human createYellowHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(YellowFemaleHuman.class);
	}

	@Override
	public Human createWhiteHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(WhiteFemaleHuman.class);
	}

	@Override
	public Human createBlackHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(BlackFemaleHuman.class);
	}

}

           

生产男性的工厂

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class MaleHumanFactory extends AbstractHumanFactory{

	@Override
	public Human createYellowHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(YellowMaleHuman.class);
	}

	@Override
	public Human createWhiteHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(WhiteFemaleHuman.class);
	}

	@Override
	public Human createBlackHuman() {
		// TODO Auto-generated method stub
		return super.createHuman(BlackMaleHuman.class);
	}

}

           

女娲开始使用工厂造人啦

package src.com.zzf.designpattern.abstractfactorypattern.demo2;

public class NvWa {
	public static void main(String[] args) {
		//第一条生产线,男性生产线
		HumanFactory maleHumanFactory = new MaleHumanFactory();
		
		//第二条生产线,女性生产线
		HumanFactory femaleHumanFactory = new FemaleHumanFactory();
		
		//生产线建立完毕,开始生产人了:
		Human maleYellowHuman = maleHumanFactory.createYellowHuman();
		
		Human femaleYellowHuman = femaleHumanFactory.createYellowHuman();
		
		maleYellowHuman.cry();
		maleYellowHuman.laugh();
		maleYellowHuman.sex();
		
		femaleYellowHuman.cry();
		femaleYellowHuman.laugh();
		femaleYellowHuman.sex();
	}
}

           

以上案例来自于设计模式之禅

代码二

定义一个顶层的产品

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public interface IProduct {
	public void show();
}

           

定义一个顶层的礼品类

package src.com.zzf.designpattern.abstractfactorypattern.demo1;

public interface IGift {
	void showGiftName();
}

           

定义清楚小米手机产品

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public class XiaoMiShouji implements IProduct{

	public void show() {
		// TODO Auto-generated method stub
		System.out.println("XiaoMiShouji show");
	}

}
           

定义清楚小米电视产品

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public class XiaomiTv implements IProduct{

	public void show() {
		// TODO Auto-generated method stub
		System.out.println("XiaomiTv");
	}

}
           

定义清楚小米电视的礼品

package src.com.zzf.designpattern.abstractfactorypattern.demo1;

public class TvGuajianGift implements IGift{

	@Override
	public void showGiftName() {
		// TODO Auto-generated method stub
		System.out.println("电视机挂件礼物");
	}

}

           

定义清楚小米手机挂件礼品

package src.com.zzf.designpattern.abstractfactorypattern.demo1;

public class ShouJiGuajianGift implements IGift{

	@Override
	public void showGiftName() {
		// TODO Auto-generated method stub
		System.out.println("手机挂件");
	}
}

           

定义清楚小米顶层的工厂类型

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public interface IFactory {
	public IProduct createProduct();
	
	public IGift createGift();
}

           

小米手机工厂

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public class XiaomiShoujiFactory implements IFactory{

	public IProduct createProduct() {
		// TODO Auto-generated method stub
		return new XiaoMiShouji();
	}

	@Override
	public IGift createGift() {
		// TODO Auto-generated method stub
		return new ShouJiGuajianGift();
	}
}

           

小米电视工厂

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


public class XiaomiTvFactory implements IFactory{

	public IProduct createProduct() {
		// TODO Auto-generated method stub
		return new XiaomiTv();
	}

	@Override
	public IGift createGift() {
		// TODO Auto-generated method stub
		return new TvGuajianGift();
	}

}

           

测试代码

package src.com.zzf.designpattern.abstractfactorypattern.demo1;


/**
 * 抽象工厂模式,工厂可以生产不同的产品类型
 * @author Administrator
 *
 */
public class FactoryMethodPatternTest {
	public static void main(String[] args) {
		//抽象工厂模式生产了手机
		IFactory mFactory = new XiaomiShoujiFactory();
		mFactory.createProduct().show();
		mFactory.createGift().showGiftName();
		
		mFactory = new XiaomiTvFactory();
		mFactory.createProduct().show();
		mFactory.createGift().showGiftName();
	}
}

           

以上两段代码都是抽象工厂模式下一种简单应用。

简单工厂模式,工厂方法模式,抽象工厂模式的区别

在这里总结一下:

1:简单工厂模式:一个工厂去生产不同的产品

2:工厂方法模式:每一个具体的产品都需要对应一个具体的工厂去生产

3:抽象工厂模式:每一个工厂可以生产不同的具体的产品。工厂是抽象的,产品族也是抽象的,抽象工厂模式较好的实现了“开放-封闭”原则,是三个模式中较为抽象,并具一般性的模式

抽象工厂模式相对其它两个工厂模式来说稍微复杂一点点,但是结合现实生活场景中也有很多场景案例。也可以很好的理解。

欢迎继续访问,我的博客

继续阅读