天天看点

23种设计模式之——抽象工厂模式

抽象工厂模式

       GOF的设计模式一书中是这样定义:为创建一组相关或相互依赖的对象提供一个接口,无需指定它们的具体类。在java程序中,它可以是接口或者抽象类。

抽象工厂模式包含:

(1)、一系列相互关联的产品类,这些产品类具有相同的结构;

(2)、一系列实的工厂类,实现由抽象工厂类提供的接口。每个工厂类生产一组相关的 产品了类对象。

当客户需要从一个相关的产品类对象中创建一个对象,而没有必要知道到底创建哪个对象时,可以使用抽象工厂模式。抽象工厂模式的类图如下:

23种设计模式之——抽象工厂模式

考虑如下问题:

       设计一个米粉的销售查询系统,查询不同米粉的价格,介绍等。为简单起见,考虑两种米粉:一种是柳州螺蛳粉(Snail powder),另一种是桂林米粉(Guilinpowder)。并且每种米粉都有二两和三两两个等级。鉴于柳州螺蛳粉和桂林米粉两类,以及他们都有相同的结构,可以考虑使用抽象工厂模式来设计销售查询系统,设计类图如下:

23种设计模式之——抽象工厂模式

假设你想要查看柳州螺蛳粉,并且你想要三两的,好,工厂满足你,下面是具体的代码实现。

首先是生产米粉的工厂,即(RiceNoodlesFactory)

public interface RiceNoodlesFactory {
	
	//用于获取柳州螺蛳粉对象
	public SnailPowder getSnailPowder();
	
	//用于获取桂林米粉对象
	public GuilinPowder getGuilinPowder();
}
           

接着是创建三两的米粉的工厂(SuperRiceNoodlesFactory)

public class SuperRiceNoodlesFactory implements RiceNoodlesFactory {

	//创建一个对象
	@Override
	public SnailPowder getSnailPowder() {
		return new SuperSnailPower();
	}

	//创建一个对象
	@Override
	public GuilinPowder getGuilinPowder() {
		return new SuperGuilinPowder();
	}

}
           

然后是创建二两米粉的工厂(MediumRiceNoodlesFactory)

public class MediumRiceNoodlesFactory implements RiceNoodlesFactory {

	//创建一个对象
	@Override
	public SnailPowder getSnailPowder() {
		return new MediumSnailPowder();
	}

	//创建一个对象
	@Override
	public GuilinPowder getGuilinPowder() {
		return new MediumGuilinPowder();
	}

}
           

接下来使柳州螺蛳粉的接口(SnailPowder)

public interface SnailPowder {
	
	// 获取关于柳州螺蛳粉的信息
	public String getSnailPowderInfo();
}
           

然后是其实现类,一个三两的柳州螺蛳粉(SuperSnailPower)

public class SuperSnailPower implements SnailPowder {

	public final String INFO = "这是一个三两的柳州螺蛳粉,要7元";
	@Override
	public String getSnailPowderInfo() {
		return INFO;
	}

}
           

接下来是二两的柳州 (MediumSnailPowder)

public class MediumSnailPowder implements SnailPowder {

	public final String INFO = "这是一个二两的柳州螺蛳粉,要6元";
	@Override
	public String getSnailPowderInfo() {
		return INFO;
	}

}
           

然后就是桂林米粉啦(GuilinPowder)

public interface GuilinPowder {

	// 获取关于桂林米粉的信息
	public String getGuilinPowderInfo();
}
           

小二,来一个三两的桂林米粉,好咧(SuperGuilinPowder)

public class SuperGuilinPowder implements GuilinPowder {

	public final String INFO = "这是一个三两的桂林米粉,要5元";
	@Override
	public String getGuilinPowderInfo() {
		return INFO;
	}

}
           

三两太多,好的,换二两(MediumGuilinPowder)

public class MediumGuilinPowder implements GuilinPowder {

	public final String INFO = "这是一个二两的桂林米粉,要4元";
	@Override
	public String getGuilinPowderInfo() {
		return INFO;
	}

}
           

终于到客户点餐啦(ClientGUI),一个三两的柳州螺蛳粉,加变态辣,好的

public class ClientGUI {

	public static void main(String[] args) {

		//创建一个三两螺蛳粉的对象工厂
		RiceNoodlesFactory rnf = new SuperRiceNoodlesFactory();
		//获取一个三两螺蛳粉的对象
		SnailPowder snailPowder = rnf.getSnailPowder();
		//获取该对象的信息
		String snailPowderInfo = snailPowder.getSnailPowderInfo();
		System.out.println(snailPowderInfo);
	}
}
           

至此,终于搞定了,哈,下面来讨论一下抽象工厂模式

抽象工厂模式的扩展性:

1、在本例中,假如客户要求有四两的螺蛳粉和桂林米粉,好,在给每个米粉接口下面添加一个四两米粉的实现即可,然后再增加一个创建四两米粉的工厂类方法,此种情况下符合开闭原则。

2、加后来又新增加了一种米粉,老友粉,此时,则要修改创建米粉的两个工厂类了,这时不不符合开闭原则。

总结一下

        无论是简单工厂模式,工厂方法模式,还是抽象工厂模式,他们都属于工厂模式,在形式和特点上也是极为相似的,工厂模式最终目的都是为了解耦合。在使用时,我们不必去在意这个模式到底工厂方法模式还是抽象工厂模式,因为他们之间的演变常常是令人琢磨不透的。 抽象工厂模式相对于工厂方法模式来说,每个具体工厂可以生产一族产品(即多种产品);而工厂方法模式是具体工厂生产相应的具体产品,只能生产一种产品。当产品族中只有一种产品时抽象工厂模式退化成工厂方法模式。