抽象工厂模式

为什么要用抽象工厂而不用工厂模式

工厂模式弥补了简单工厂不满足开闭原则的缺点。那么抽象工厂就是为了弥补工厂模式冗杂的代码量的模式。

简单工厂下,所有的产品都在一个工厂下生产;而工厂模式下,产品的生产又交给到每一个工厂。两个方式都很极端,要么全部生产,要么只生产一件。在两者极端中折中一下就产生了抽象工厂模式。
抽象工厂模式简单的说就是按需生产,一个工厂不只生产一种产品,而是生产一系列产品,使每个工厂都按照相同的模板去生产一系列不同的产品。这里的一系列产品被称作产品族。而按照那个相同的模板就是产品等级结构,有点难理解这里放上《C#设计模式》中的概念图。

抽象工厂模式_第1张图片

产品族与产品等级结构

务必要结合上图进行理解

产品等级结构:产品等级结构即产品的继承结构,例如一个抽象类是电视机,其子类包括海尔电视机、海信电视机、HTC电视机,则抽象电视机与具体的品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而记忆体品牌的电视机是其子类。
产品族:在抽象工厂模式中,产品族是指由同一个工厂产生的,位于不同产品等级结构中的一组产品。例如海尔电器工厂生产的海尔电视机、海尔电冰箱、海尔空调,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中,空调位于空调的产品等级结构中。这样的海尔电视机、海尔电冰箱、海尔空调就构成了一个产品族。

关于这两者的理解,目前只需要了解产品等级结构是某类产品的合集就可以了,而产品族则是每个合集中的实例的合集。

这里提供了产品族内容数量为2,产品等级结构也为2的抽象工厂模式的类图。

抽象工厂模式

我们用格力公司和美的公司来举例,同样生产冰箱与空调。
现在我们有四种产品,格力冰箱,格力空调,美的冰箱,美的空调。
工厂模式:建立一座抽象工厂,实例四座具体工厂,分别生产四种产品。
而抽象工厂模式则要根据产品等级结构与产品族来划分(怎么划分稍后说)。
根据上面的类图进行编写。

根据产品等级结构来写产品类

//冰箱
abstract class AbstractProduct_BingXiang
{
	public abstract void Show();
}  
public class MeiDi_BingXiang:AbstractProduct_BingXiang
{
	public override void Show()
	{
		Console.WriteLine("美的冰箱");
	}
}
public class GeLi_BingXiang:AbstractProduct_BingXiang
{
	public override void Show()
	{
		Console.WriteLine("格力冰箱");
	}
}
//空调
abstract class AbstractProduct_KongTiao
{
	public abstract void Show();
}  
public class MeiDi_KongTiao:AbstractProduct_KongTiao
{
	public override void Show()
	{
		Console.WriteLine("美的空调");
	}
}
public class GeLi_KongTiao:AbstractProduct_KongTiao
{
	public override void Show()
	{
		Console.WriteLine("格力空调");
	}
}

根据产品族来写工厂类

abstract class AbstractFactory
{
	public abstract AbstractProduct_BingXiang CreateBingXiang();
	public abstract AbstractProduct_KongTiao CreateKongTiao();
}
//美的工厂
public class Factory_MeiDi:AbstractFactory
{
	public override AbstractProduct_BingXiang CreateBingXiang()
	{
		return new MeiDi_BingXiang();
	}
	public override AbstractProduct_KongTiao CreateKontTiao()
	{
		return new MeiDi_KongTiao();
	}
}
//格力工厂
public class Factory_GeLi:AbstractFactory
{
	public override AbstractProduct_BingXiang CreateBingXiang()
	{
		return new GeLi_BingXiang();
	}
	public override AbstractProduct_KongTiao CreateKontTiao()
	{
		return new GeLi_KongTiao();
	}
}

这个时候的Client类

class Client
{
	 static void Main(string[] args)
     {
        AbstractFactory factory=new Factory_GeLi();//可以读取配置文件实例创建
        AbstractProduct_BingXiang bingxiang=factory.CreateBingXiang();
        AbstractProduct_KongTiao kongtiao=factory.CreateKontTiao();
        bingxiang.Show();
        kongtiao.Show();
     }
}

输出结果:

格力冰箱
格力空调

产品族与产品等级结构的划分

从上面的例子可以总结出,产品族内产品个数对应着抽象工厂类的Create方法个数。而产品等级结构则对应着抽象产品类的划分。本例子中,将冰箱与空调作为两个产品等级,每个等级又分了美的和格力两个产品族。美的格力的产品族内又有不同产品等级结构中的产品。这样的交叉组合十分的灵活,例子中完全可以将美的与格力作为产品等级,将空调与冰箱作为两个产品族。到底怎么去确定这两者,就要规划未来谁的扩展性高了。

开闭原则的倾斜性

说到扩展性,其实就是为了满足开闭原则,就上面举得例子而言,建立了美的与格力工厂,当第三个品牌加入时,不需要修改原代码就可以创建,因为第三个品牌也生产相同的两种东西:冰箱和空调。但是当美的和格力要创新了,可能现在又要生产电视机了,那么开闭原则就无法遵守了。这时便要换个角度去思考,就要将冰箱和空调作为产品族,当多了电视机时,依然满足开闭原则。这就称为开闭原则的倾斜性,也就需要代码编写人员在编写前就要确定好整体的框架。

总结

抽象工厂模式相对于工厂模式引入了产品族和产品等级结构的概念。这也就很好的展示出了抽象共产模式的应用范围,当项目中的产品具有较多相同点,且划分为产品等级结构的就可以采用抽象工厂模式。
为了避免开闭原则的倾斜性,可以在项目初期运用工厂模式,对外暴露抽象工厂模式的接口,等到中后期基本确定时,再对工厂模式的代码进行修改,全面修改成抽象工厂模式。

你可能感兴趣的:(设计模式)