首页 > 代码库 > 设计模式 工厂模式 从卖肉夹馍说起

设计模式 工厂模式 从卖肉夹馍说起

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/24460585

今天继续设计模式之旅,给大家带来工厂模式,简单列一下这个模式的家族:

1、静态工厂模式

2、简单工厂模式

3、工厂方法模式

4、抽象工厂模式

是不是认为,我勒个去,这工厂还能列出这么多分类,哈哈,以下開始各个击破。

1、静态工厂模式

这个最常见了,项目中的辅助类,TextUtil.isEmpty等,类+静态方法。以下開始具体介绍:略。

2、简单工厂模式

以下開始谈谈卖肉夹馍,近期程序猿卖肉夹馍非常火,啥时候大牛们都去卖了,我等就崛起了,哈哈。

首先你得有个店:RoujiaMoStore

package com.zhy.pattern.factory.a;

public class RoujiaMoStore
{

	/**
	 * 依据传入类型卖不同的肉夹馍
	 * 
	 * @param type
	 * @return
	 */
	public RouJiaMo sellRouJiaMo(String type)
	{
		RouJiaMo rouJiaMo = null;
		
		if (type.equals("Suan"))
		{
			rouJiaMo = new SuanRouJiaMo();

		} else if (type.equals("Tian"))
		{
			rouJiaMo = new TianRouJiaMo();
		} else if (type.equals("La"))
		{
			rouJiaMo = new LaRouJiaMo();
		}
		
		rouJiaMo.prepare();
		rouJiaMo.fire();
		rouJiaMo.pack();
		return rouJiaMo;
	}

}

然后你得有各种风味的馍馍:

package com.zhy.pattern.factory.a;

public abstract class RouJiaMo
{
	protected String name;

	/**
	 * 准备工作
	 */
	public void prepare()
	{
		System.out.println("揉面-剁肉-完毕准备工作");
	}

	/**
	 * 使用你们的专用袋-包装
	 */
	public void pack()
	{
		System.out.println("肉夹馍-专用袋-包装");
	}
	/**
	 * 秘制设备-烘烤2分钟
	 */
	public void fire()
	{
		System.out.println("肉夹馍-专用设备-烘烤");
	}
}

package com.zhy.pattern.factory.a;

import com.zhy.pattern.factory.a.RouJiaMo;

/**
 * 辣味肉夹馍
 * 
 * @author zhy
 * 
 */
public class LaRouJiaMo extends RouJiaMo
{
	public LaRouJiaMo()
	{
		this.name = "辣味肉夹馍";
	}
}

package com.zhy.pattern.factory.a;



/**
 * 酸味肉夹馍
 * 
 * @author zhy
 * 
 */
public class SuanRouJiaMo extends RouJiaMo
{
	public SuanRouJiaMo()
	{
		this.name = "酸味肉夹馍";
	}
}

package com.zhy.pattern.factory.a;



/**
 * 酸味肉夹馍
 * 
 * @author zhy
 * 
 */
public class SuanRouJiaMo extends RouJiaMo
{
	public SuanRouJiaMo()
	{
		this.name = "酸味肉夹馍";
	}
}

如今这种设计,尽管能够支持你卖肉夹馍了,可是有点问题,生产馍的种类和你的RoujiaMoStore耦合度太高了,假设添加?几种风味,删除几种风味,你得一直改动sellRouJiaMo中的方法,所以我们须要做一定的改动,此时简单工厂模式就能派上用场了。

我们開始写个简单工厂,把产生馍的过程拿出来:

package com.zhy.pattern.factory.a;

public class SimpleRouJiaMoFactroy
{
	public RouJiaMo createRouJiaMo(String type)
	{
		RouJiaMo rouJiaMo = null;
		if (type.equals("Suan"))
		{
			rouJiaMo = new SuanRouJiaMo();

		} else if (type.equals("Tian"))
		{
			rouJiaMo = new TianRouJiaMo();
		} else if (type.equals("La"))
		{
			rouJiaMo = new LaRouJiaMo();
		}
		return rouJiaMo;
	}

}

然后以组合的方式,让Store来使用:

package com.zhy.pattern.factory.a;

public class RoujiaMoStore
{
	private SimpleRouJiaMoFactroy factroy;

	public RoujiaMoStore(SimpleRouJiaMoFactroy factroy)
	{
		this.factroy = factroy;
	}

	/**
	 * 依据传入类型卖不同的肉夹馍
	 * 
	 * @param type
	 * @return
	 */
	public RouJiaMo sellRouJiaMo(String type)
	{
		RouJiaMo rouJiaMo = factroy.createRouJiaMo(type);
		rouJiaMo.prepare();
		rouJiaMo.fire();
		rouJiaMo.pack();
		return rouJiaMo;
	}

}

好了,如今你随便加入?什么种类的馍,删除什么种类的馍就和Store无关了,就是么~人家仅仅负责卖馍么~ 这就是简单工厂模式,当然了,大家也都比較熟悉。

3、工厂方法模式

定义:定义一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法模式把类实例化的过程推迟到子类。

好了,看完定义,以下我们用样例来展示。继续肉夹馍,因为使用了简单工厂模式,肉夹馍生意那个好啊,所以下载决定去西安开个分店,去北京开个分店。既然有分店了,那总店就是抽象的了:

package com.zhy.pattern.factory.b;

public abstract class RoujiaMoStore
{

	public abstract RouJiaMo createRouJiaMo(String type);

	/**
	 * 依据传入类型卖不同的肉夹馍
	 * 
	 * @param type
	 * @return
	 */
	public RouJiaMo sellRouJiaMo(String type)
	{
		RouJiaMo rouJiaMo = createRouJiaMo(type);
		rouJiaMo.prepare();
		rouJiaMo.fire();
		rouJiaMo.pack();
		return rouJiaMo;
	}

}

然后在开两个分店,这里拿一个代码做演示,其它都一样:

package com.zhy.pattern.factory.b;



/**
 * 西安肉夹馍店
 * 
 * @author zhy
 * 
 */
public class XianRouJiaMoStore extends RoujiaMoStore
{

	@Override
	public RouJiaMo createRouJiaMo(String type)
	{
		RouJiaMo rouJiaMo = null;
		if (type.equals("Suan"))
		{
			rouJiaMo = new XianSuanRouJiaMo();

		} else if (type.equals("Tian"))
		{
			rouJiaMo = new XianTianRouJiaMo();
		} else if (type.equals("La"))
		{
			rouJiaMo = new XianLaRouJiaMo();
		}
		return rouJiaMo;

	}

}

然后就是各个西安口味的肉夹馍了,这代码就不贴了。能够看出我们把制作肉夹馍的过程以抽象方法的形式让子类去决定了,对比定义:

1、定义了创建对象的一个接口:public abstract RouJiaMo createRouJiaMo(String type);

2、由子类决定实例化的类,能够看到我们的馍是子类生成的。

可能有人会说,我用简单工厂模式也行啊,可是假设10来个城市*5种风味/城市,那么岂不是简单工厂里面须要50多个if,再说人家西安肉夹馍分店就不能有点自己的秘诀,当然由它自己定最好。

好了,方法工厂模式介绍完成。

4、抽象工厂模式

定义:提供一个接口,用于创建相关的或依赖对象的家族,而不须要明白指定详细类。

这定义有点绕口,算了,还是拿样例来说。继续卖肉夹馍,咱们生意这么好,难免有些分店開始动歪脑子,開始使用劣质肉等,砸我们的品牌。所以我们要拿钱在每一个城市建立自己的原料场,保证高质量原料的供应。

于是我们新建一个提供原料的接口:

package com.zhy.pattern.factory.b;

/**
 * 提供肉夹馍的原料
 * @author zhy
 *
 */
public interface RouJiaMoYLFactroy
{
	/**
	 * 生产肉
	 * @return
	 */
	public Meat createMeat();
	
	/**
	 * 生产调料神马的
	 * @return
	 */
	public YuanLiao createYuanliao();
	
}

package com.zhy.pattern.factory.b;

/**
 * 依据西安当地特色,提供这两种材料
 * @author zhy
 *
 */
public class XianRouJiaMoYLFactroy implements RouJiaMoYLFactroy
{

	@Override
	public Meat createMeat()
	{
		return new FreshMest();
	}

	@Override
	public YuanLiao createYuanliao()
	{
		return new XianTeSeYuanliao();
	}

}

有了原理工厂,那我们略微改动下RouJiaMo的prepare方法:

package com.zhy.pattern.factory.b;

public abstract class RouJiaMo
{
	protected String name;

	/**
	 * 准备工作
	 */
	public final void prepare(RouJiaMoYLFactroy ylFactroy)
	{
		Meat meat = ylFactroy.createMeat();
		YuanLiao yuanliao = ylFactroy.createYuanliao();
		System.out.println("使用官方的原料" + meat + " , " + yuanliao + "作为原材料制作肉夹馍 ");
	}

	/**
	 * 使用你们的专用袋-包装
	 */
	public final void pack()
	{
		System.out.println("肉夹馍-专用袋-包装");
	}

	/**
	 * 秘制设备-烘烤2分钟
	 */
	public final void fire()
	{
		System.out.println("肉夹馍-专用设备-烘烤");
	}
}

好了,如今必须用我们官方原料做为原材料了。

如今对照定义:

1、提供一个接口:public interface RouJiaMoYLFactroy

2、用于创建相关的或依赖对象的家族 public Meat createMeat();public YuanLiao createYuanliao();我们接口用于创建一系列的原材料。

好了,最后測试下,我要在西安馍店,买个酸味的尝尝:

package com.zhy.pattern.factory.b;


public class Test
{
	public static void main(String[] args)
	{
		
		RoujiaMoStore roujiaMoStore = new XianRouJiaMoStore();
		RouJiaMo suanRoujiaMo = roujiaMoStore.sellRouJiaMo("Suan");
		System.out.println(suanRoujiaMo.name);
	}
}

使用官方的原料com.zhy.pattern.factory.b.FreshMest@e53108 , com.zhy.pattern.factory.b.XianTeSeYuanliao@f62373作为原材料制作肉夹馍 
肉夹馍-专用设备-烘烤
肉夹馍-专用袋-包装
酸味肉夹馍

哈哈~肉夹馍店的已经建立起来了,兄弟们卖馍去把~记得留个言,给个赞~






设计模式 工厂模式 从卖肉夹馍说起