设计模式之--工厂模式详解(简单工厂、工厂方法、抽象工厂)

工厂模式

1、定义

工厂模式很简单,就是用来创建对象实例的,所有的对象实例,都交给工厂类生成。

2、类型

简单工厂、工厂方法、抽象工厂

以下是笔者对这三种工厂模式的一些个人理解,希望对读者有帮助!


简单工厂

简单工厂模式的工厂类一般是使用静态方法,通过接收的参数的不同来返回不同的对象实例。



优点:实现客户与具体实现类的松耦合,对于客户来说,他只需要传入对象的类型参数,就可以通过工厂获得所需要的对象实例


缺点:1、与具体实现类松耦合,却又和工厂绑在了一起

            2、当有新的对象加入时,得修改工厂类的代码


简单工厂模型

代码实现:

/**
 * 简单工厂模式
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:15:17
 */
public class Client_SimpleFactory {

	public static void main(String[] args) {
		//在不实用简单工厂模式前
		/*
		//买小米
		Mobie xiaomi = new Xiaomi();
		xiaomi.getMobie();
		
		//买iphone
		Mobie iphone = new IPhone();
		iphone.getMobie();
		
		//买华为
		Mobie huawei = new Huawei();
		huawei.getMobie();*/
		
		//使用了简单工厂之后,买什么手机直接告诉工厂,
		//不需要客户去到每一个专卖店买(这里只是为了说明工厂模式作的比喻)
		
		SimpleFactory sf = new SimpleFactory();
		//买小米
		sf.getMobie("xiaomi").getMobie();
		
		//买iphone
		sf.getMobie("iphone").getMobie();
		
		//买华为
		sf.getMobie("huawei").getMobie();
	}
}

/**
 * 抽象手机类
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:24:45
 */
interface Mobie{
	abstract void getMobie();
}

/**
 * 具体手机--小米
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:25:52
 */
class Xiaomi implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是小米手机……");
		
	}
	
}

/**
 * 具体手机--iphone
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:26:32
 */
class IPhone implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是苹果手机……");
		
	}
	
}

/**
 * 具体手机--华为手机
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:27:44
 */
class Huawei implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是华为手机……");
		
	}
	
}

/**
 * 简单工厂
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:32:27
 */
class SimpleFactory{
	
	/**
	 * 工厂根据类型生产手机
	 * @param type
	 * @return Mobie
	 */
	public static Mobie getMobie(String type){
		Mobie mobie = null;
		
		switch(type){
		case "xiaomi" : mobie = new Xiaomi();break;
		case "iphone" : mobie = new IPhone();break;
		case "huawei" : mobie = new Huawei();break;
		}
		return mobie;
	}
	
}


工厂方法

工厂方法是针对每一种产品提供一个工厂类。通过不同的工厂实例来创建不同的产品实例。在同一等级结构中,支持增加任意产品。

工厂方法模型

代码实现:

/**
 * 工厂方法设计模式
 * @Author 先
 * @ClassName Client_FactoryMethod.java
 * @Time 2017年3月12日 下午1:46:22
 */
public class Client_FactoryMethod {

	public static void main(String[] args) {
		//使用工厂方法模式
		
		//买小米,找小米手机工厂
		Factory f_xiaomi = new Factory_xiaomi();
		f_xiaomi.produce_Mobie().getMobie();
		
		//买iphone,找iphone手机工厂
		Factory f_iphone = new Factory_iphone();
		f_iphone.produce_Mobie().getMobie();
		
		//买华为,找华为工厂
		Factory f_huawei = new Factory_huawei();
		f_huawei.produce_Mobie().getMobie();
	}
}

/**
 * 抽象手机类
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:24:45
 */
interface Mobie{
	abstract void getMobie();
}

/**
 * 具体手机--小米
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:25:52
 */
class Xiaomi implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是小米手机……");
		
	}
	
}

/**
 * 具体手机--iphone
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:26:32
 */
class IPhone implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是苹果手机……");
		
	}
	
}

/**
 * 具体手机--华为手机
 * @Author 先
 * @ClassName Client_SimpleFactory.java
 * @Time 2017年3月12日 下午1:27:44
 */
class Huawei implements Mobie{

	@Override
	public void getMobie() {
		System.out.println("我是华为手机……");
		
	}
	
}

/**
 * 抽象工厂
 * @Author 先
 * @ClassName Client_FactoryMethod.java
 * @Time 2017年3月12日 下午1:48:32
 */
interface Factory{
	abstract Mobie produce_Mobie();
}

/**
 * 小米工厂,小米系列的手机由它生产
 * @Author 先
 * @ClassName Client_FactoryMethod.java
 * @Time 2017年3月12日 下午1:51:40
 */
class Factory_xiaomi implements Factory{

	@Override
	public Mobie produce_Mobie() {
		Mobie mobie = new Xiaomi();
		return mobie;
	}
	
}

/**
 * iphone工厂,苹果系列的手机由它生产
 * @Author 先
 * @ClassName Client_FactoryMethod.java
 * @Time 2017年3月12日 下午1:52:30
 */
class Factory_iphone implements Factory{

	@Override
	public Mobie produce_Mobie() {
		Mobie mobie = new IPhone();
		return mobie;
	}
	
}

/**
 * 华为工厂,华为系列的手机由它生产
 * @Author 先
 * @ClassName Client_FactoryMethod.java
 * @Time 2017年3月12日 下午1:52:41
 */
class Factory_huawei implements Factory{

	@Override
	public Mobie produce_Mobie() {
		Mobie mobie = new Huawei();
		return mobie;
	}
	
}
分析:

使用开闭原则来分析下工厂方法模式。当有新的产品产生时,只要按照抽象产品角色、抽象工厂角色提供的合同(即接口)来生成,那么就可以被客户使用,而不必去修改任何已有的代码。(即当有新产品时,只要创建并继承抽象产品;新建具体工厂继承抽象工厂;而不用修改任何一个类)工厂方法模式是完全符合开闭原则的!


抽象工厂

在认识抽象工厂前,我们得先认识一下产品族。

所谓的产品族,就是位于不同产品等级结构中,功能相关联的产品组成的家族


先看抽象工厂的模型图


我们可以看到,抽象工厂中利用到了工厂方法的方式实现,但又有所不同,所以在此将抽象工厂与工厂方法加以区分。

抽象工厂与工厂方法的区别

1、抽象工厂模式是工厂方法模式的升级版本(因为用到了工厂方法的实现方式),他用来创建一组相关或者相互依赖的对象。工厂方法模式针对的是一个产品等级结构;而抽象工厂模式则是针对的多个产品等级结构。在编程中,通常一个产品结构,表现为一个接口或者抽象类,也就是说,工厂方法模式提供的所有产品都是衍生自同一个接口或抽象类,而抽象工厂模式所提供的产品则是衍生自不同的接口或抽象类

2、抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构

我们先看一个例子,再做详细分析

/**
 * 抽象工厂模式
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午1:58:21
 */
public class Client_AbstractFactory {

	public static void main(String[] args) {
		//现在,需要小米屏幕
		
		//1、找屏幕工厂(创建屏幕工厂对象)
		AbstractFactory af = new ScreenFactory();
		
		//2、屏幕工厂里生产出小米的屏幕
		XiaomiComponent xiaomiScreen = af.Xiaomi();
		
		//3、得到小米屏幕
		xiaomiScreen.produceComponent();
		
		
		//若需要其他产品,操作类似
	}
}

/**
 * 抽象工厂,这里生产一些手机的零件
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午4:56:08
 */
interface AbstractFactory{
	//小米零件
	abstract XiaomiComponent Xiaomi();
	
	//华为零件
	abstract HuaweiComponent Huawei();
}

/**
 * 具体零件工厂--屏幕工厂
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午6:56:04
 */
class ScreenFactory implements AbstractFactory{

	//小米屏幕
	@Override
	public XiaomiComponent Xiaomi() {
		XiaomiComponent xiaomiScreen = new XiaomiScreen();
		return xiaomiScreen;
	}

	//华为屏幕
	@Override
	public HuaweiComponent Huawei() {
		HuaweiComponent huaweiScreen = new HuaweiScreen();
		return huaweiScreen;
	}

	
}

/**
 * 具体工厂--电池工厂
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:10:56
 */
class BatteryFactory implements AbstractFactory{

	//小米电池
	@Override
	public XiaomiComponent Xiaomi() {
		XiaomiComponent xiaomiBattery = new XiaomiBattery();
		return xiaomiBattery;
	}

	//华为电池
	@Override
	public HuaweiComponent Huawei() {
		HuaweiComponent huaweiBattery = new HuaweiBattery();
		return huaweiBattery;
	}

	
}

/**
 * 抽象产品--小米零件
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:03:02
 */
interface XiaomiComponent{
	//生产小米零件
	abstract void produceComponent();
}

/**
 * 抽象产品--华为零件
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:07:27
 */
interface HuaweiComponent{
	//生产华为零件
	abstract void produceComponent();
}

/**
 * 具体产品--小米屏幕
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:05:04
 */
class XiaomiScreen implements XiaomiComponent{

	@Override
	public void produceComponent() {
		System.out.println("小米屏幕生产完毕!");
		
	}
	
}

/**
 * 具体产品--小米电池
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:06:22
 */
class XiaomiBattery implements XiaomiComponent{

	@Override
	public void produceComponent() {
		System.out.println("小米电池生产完毕!");
		
	}
	
}

/**
 * 具体产品--华为屏幕
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:08:04
 */
class HuaweiScreen implements HuaweiComponent{

	@Override
	public void produceComponent() {
		System.out.println("华为屏幕生产完毕!");
		
	}
	
}

/**
 * 具体产品--华为电池
 * @Author 先
 * @ClassName Client_AbstractFactory.java
 * @Time 2017年3月12日 下午7:09:01
 */
class HuaweiBattery implements HuaweiComponent{

	@Override
	public void produceComponent() {
		System.out.println("华为电池生产完毕!");
		
	}
	
}

在上例子中,小米零件和华为零件就分别为一个等级结构(小米结构,华为结构,我们勉强这么理解),而电池和屏幕就分别为一个产品族(电池产品、屏幕产品)。在这里,小米电池和小米屏幕就是同一个等级结构,而小米电池和华为电池就是同一个产品族。正如上述所说,如果一个工厂生产的产品来自同一个接口或抽象类,那么属于工厂方法;如果一个工厂生产的产品来自不同的接口,那么属于抽象工厂,很明显,上例子中,无论是电池工厂还是屏幕工厂,他们的产品都来自不同接口,并且在各自的接口中,它们属于同一类产品(即都为电池或者都为屏幕)。现在,应该明白什么叫抽象工厂了吧,也能区分工厂方法和抽象工厂了吧。


总结

1、工厂模式中,重要的是工厂类,而不是产品类;

2、使用工厂模式,返回的实例一定是工厂创建的,而不是从其他对象中获取的。这也正是工厂模式的宗旨(或者说存在的意义)--创建对象实例;

3、简单工厂--对于增加新的产品,无能为力;

4、工厂方法--支持增加任意产品(常用);

5、抽象工厂--对于增加新的产品,无能为力;支持增加产品族(这句话的意思是,用上例来说,如果增加一个新的产品(比如魅族电池),那么得改写原有代码,很麻烦;但如果加入的是一个产品族(如手机壳),抽象工厂是很容易做到的,即再创建一个手机壳工厂,这个工厂依然是实现抽象工厂,在这个工厂里,生产小米手机壳和华为手机壳,这样的做法是不需要改动原来代码的)。

注:转载请注明出处!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yeqiu1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值