天天看點

【設計模式十之抽象工廠模式】抽象工廠模式詳解細說抽象工廠模式

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:抽象工廠模式:每一個工廠可以生産不同的具體的産品。工廠是抽象的,産品族也是抽象的,抽象工廠模式較好的實作了“開放-封閉”原則,是三個模式中較為抽象,并具一般性的模式

抽象工廠模式相對其它兩個工廠模式來說稍微複雜一點點,但是結合現實生活場景中也有很多場景案例。也可以很好的了解。

歡迎繼續通路,我的部落格

繼續閱讀