抽象工厂模式

转自:《Java 设计模式》2009年( 耿祥义 张跃平 著)

一,概括

抽象工厂模式(别名:配套)

  提供一个创建一系列或相互依赖对象的接口,而无需指定他们具体的类

二,引入

设计某些系统是可能需要为用户提供一系列相关的对象,但系统不希望用户直接使用 new运算符 实例化这些对象,而是应由系统控制这些对象的创建。否则用户不仅要知道用哪些类来创建对象,而且还必须清楚这些对象之间是怎么相关的,使得用户的代码与这些类形成耦合,不利于维护。

比如:商家要去工厂采购衣服裤子,这些商家自然不能自己生产衣服(直接使用 new运算符 实例化这些对象,用哪些类来创建对象).这些商家只能来到特定的工厂,他们自然会提供给你提供他们品牌的衣服。其中这些工厂是有生产配套的衣服和裤子的,商家也无需事先了解哪些衣服和裤子是一套的(对象之间是怎么相关的),工厂直接就提供给你一整套的衣物,这些衣物配套生产,这些商家也无法单独购买。商家只需要对工厂提供给你的样品衣物中做出选择,是否购买。

三,代码与类图

衣服有两种衣服,江牌风衣和鸟牌衬衫;裤子有两种裤子,江牌牛仔裤和鸟牌裙子;工厂有两座,一个是江牌的工厂。一个是鸟牌的工厂。

package MM;

/*************************
	Clothes
*************************/
abstract class Clothes
{
	abstract public int getChestSize();
	abstract public int getHeight();
	abstract public String getName();
}
class WindCoat extends Clothes
{
	public int getChestSize()
	{
		return 90;
	}
	public int getHeight()
	{
		return 175;
	}
	public String getName()
	{
		return "江牌风衣";
	}
}
class Shirt extends Clothes
{
	public int getChestSize()
	{
		return 90;
	}
	public int getHeight()
	{
		return 170;
	}
	public String getName()
	{
		return "鸟牌衬衫";
	}
}

/*************************
	Pants
*************************/
abstract class Pants
{
	abstract public int getWaistSize();
	abstract public int getHeight();
	abstract public String getName();
}
class Jeans extends Pants
{
	public int getWaistSize()
	{
		return 75;
	}
	public int getHeight()
	{
		return 175;
	}
	public String getName()
	{
		return "江牌牛仔裤";
	}
}
class Skirt extends Pants
{
	public int getWaistSize()
	{
		return 62;
	}
	public int getHeight()
	{
		return 170;
	}
	public String getName()
	{
		return "鸟牌裙子";
	}
}

/*************************
	Factory
*************************/
abstract class Factory
{
	public Factory()
	{
		System.out.printf("生产了一套衣物:
");
		System.out.printf(createClothes().getName() + ": 
");
		System.out.printf("*胸围:" + createClothes().getChestSize() + "
");
		System.out.printf("*身高:" + createPants().getHeight() + "
");
		System.out.printf(createPants().getName() + ": 
");
		System.out.printf("*腰围:" + createPants().getWaistSize() + "
");
		System.out.printf("*身高:" + createPants().getHeight() + "
");
		System.out.printf("
");
	}
	abstract public Clothes createClothes();
	abstract public Pants createPants();
}
class JiangFactory extends Factory
{
	public Clothes createClothes()
	{
		return new WindCoat();
	}
	public Pants createPants()
	{
		return new Jeans();
	}
}
class NiaoFactory extends Factory
{
	public Clothes createClothes()
	{
		return new Shirt();
	}
	public Pants createPants()
	{
		return new Skirt();
	}
}

public class M
{
	public static void main(String L[])
	{
		Clothes c;
		Pants p;
		Factory f;
 
    		f = new JiangFactory();
        		c = f.createClothes();
		p = f.createPants();
 
       		f = new NiaoFactory();
		c = f.createClothes();
		p = f.createPants();
	}
}

类图:

 (注: 由于找不到合适的箭头,这箭头就画的不标准了)

四,工厂方法模式的结构

① 抽象产品(Product): Clothes类 和 Pants类

② 具体产品(ConcreteProduct):  WindCoat类 和 Shirt类 和 Jeans类 和 Skirt类

③ 抽象工厂(Creator): Factory类

④ 具体工厂(ConcreteCreator): JiangFactory1类  和 NiaoFactory类

五,抽象工厂模式的优缺点

优点:

① 抽象工厂模式可以为用户创建一系列相关的对象,使用户和创建这些对象的类脱耦。

② 用户使用不同的具体工厂就能得到一组相关的对象,可以避免用户混用不同系列中的对象。

③ 在抽象工厂模式中,可以随时增加 “具体工厂”,为用户提供一组相关的对象。

缺点:一旦原有的实体类进行扩充,就无法正常工作,(如在上述例子中,还要给 江牌 的套装增加一双袜子,就必须修改抽象工厂的代码了)

 六,抽象工厂模式的使用场景

① 系统需要为用户提供多个对象,又希望用户和创建对象的类脱耦。

② 系统需要为用户提供多个相关的对象,当又不希望用户决定这些对象是如何关联的。

③ 系统需要用户提供一系列对象,用户只需要知道有这些对象有哪些方法可用,不需要知道这些对象的创建过程。

七,抽象工厂模式的使用

用户在使用抽象工厂模式时,只和抽象产品,抽象工厂以及具体构工厂打交道,用户只需了解抽象产品有哪些方法,不需要知道有哪些具体产品。

抽象工厂方法模式的关键是 在一个接口或抽象类中定义若干个 抽象方法(抽象工厂),这些方法分别返回某个类的子类的实例,该抽象类或接口 让其 子类或实现该接口的类(具体工厂) 通过重写这些抽象方法 为用户提供一系列相关的对象

=========== ========= ======== ======= ===== ==== === == =

蝶恋花  宋代: 柳永

独倚危楼风细细,望极春愁,黯黯生天际。
草色烟光残照里,无言谁会凭阑意。
拟把疏狂图一醉,对酒当歌,强乐还无味。
衣带渐宽终不悔,为伊消得人憔悴。
原文地址:https://www.cnblogs.com/asdfknjhu/p/13962979.html