[Android设计模式之旅]————工厂模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;设计模式是软件工程的基石脉络,如同大厦的结构一样。
工厂模式主要有三类:
1、(静态工厂模式)简单工厂模式
2、工厂方法模式
3、抽象工厂模式
1、简单(静态)工厂模式 SimpleFactory
看了鸿洋大神的博客,写得真有趣。他从买肉夹馍开始介绍,我仿照他的写了个卖拉面的例子。
首先,同样你得有个店:LaMianStore
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class LaMianStore {
/**
* 根据传入的不同类型拉不同的拉面
*/
public LaMian SellLaMian(String type){
LaMian laMian = null;
if (type.equals("二细")){
laMian = new ErXiLamian();
}else if (type.equals("毛细"))
{
laMian = new MaoXiLamian();
}else if (type.equals("宽拉面")){
laMian = new KuanLaMian();
}
laMian.prepare();;
laMian.Lamian();
laMian.ZhuMian();
return laMian;
}
}
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public abstract class LaMian {
protected String name;
/**
* 准备工作
*/
public void prepare()
{
System.out.print("揉面-熬汤-烧水等准备工作");
}
/**
* 拉面
*/
public void Lamian ()
{
System.out.print("开始拉面工作");
}
/**
* 煮面
*/
public void ZhuMian ()
{
System.out.print("煮面工作");
}
}
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class ErXiLamian extends LaMian {
/**
* 二细拉面
*/
public ErXiLamian()
{
this.name = "二细拉面";
}
}
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class KuanLaMian extends LaMian {
public KuanLaMian(){
this.name = "宽面";
}
}
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class MaoXiLamian extends LaMian{
public MaoXiLamian(){
this.name = "毛细拉面";
}
}
现在的设计,虽说可以支持卖拉面,但是有点问题,拉面的种类和LaMianStore藕合度太高了,如果增加几种拉面或是删除几种拉面,那我们就得一直修改sellLaMian中的方法 ,所以我们需要做一定的修改,此时我们可以考虑简单工厂模式。
我们开始写个简单工厂,把制作拉面的过程拿出来:
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class LaMianFactory {
public LaMian createLaMian(String type){
LaMian laMian = null;
if (type.equals("二细")){
laMian = new ErXiLamian();
}else if (type.equals("毛细"))
{
laMian = new MaoXiLamian();
}else if (type.equals("宽拉面")){
laMian = new KuanLaMian();
}
return laMian;
}
}
然后把LaMianStore修改如下:
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public class LaMianStore {
private LaMianFactory factory;
public LaMianStore(LaMianFactory factory){
this.factory = factory;
}
/**
* 根据传入的不同类型拉不同的拉面
*/
public LaMian SellLaMian(String type){
LaMian laMian = factory.createLaMian(type);
laMian.prepare();;
laMian.Lamian();
laMian.ZhuMian();
return laMian;
}
}
这就是简单工厂模式,LaMianStore只负责卖拉面就好,其他法的什么各种拉面都与我无关,让工厂去生产就好拉。
2、工厂方法模式
定义:定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例化推迟到子类。
所谓的决定并不是批模式允许子类本身在运行时做决定,而是指在编写创建者类时,不需知道创建的产品是哪一个,选择了使用哪个子类,就决定了实际创建的产品是什么。
我们继续卖拉面,由于拉面生意火爆,所以老板决定在杭州,兰州,西安开分店。既然有了分店那么总店呢,成为抽象的啦:
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public abstract class LaMianStore {
public abstract LaMian createLaMian(String type);
/**
* 根据传入的不同类型拉不同的拉面
*/
public LaMian SellLaMian(String type){
LaMian laMian = factory.createLaMian(type);
laMian.prepare();;
laMian.Lamian();
laMian.ZhuMian();
return laMian;
}
}
然后再来开三个分店,这里只拿一个代码来做演示:
package com.example;
/**
* Created by leiqi on 16-5-13.
*/
public class HangZhouLaMianStore extends LaMianStore {
/**
* 杭州拉面分店
*/
@Override
public LaMian createLaMian(String type){
LaMian laMian = null;
if (type.equals("二细")){
laMian = new HZErXiLamian();
}else if (type.equals("毛细"))
{
laMian = new HZMaoXiLamian();
}else if (type.equals("宽拉面")){
laMian = new HZKuanLaMian();
}
return laMian;
}
}
关于杭州所有种类的拉面就不贴拉。可以看出我们把制作拉面的过程以抽象方法的形式让子类取决定拉,对照定义:
1、定义拉创建对象的一个接口: public abstract LaMian createLaMian(String type);
2、由子类决定实例化的类,可以看到我们的拉面是子类生产的,也就是分店成产的。
这不是简单工厂模式来也能实现吗?但是没想到这个问题:如果我要开20个分店 X 6中面/分店,那么简单工厂就得多120个if来判断,很不划算啊,再说每个分店都有自己独特的秘方和经验,当然是自己定最好拉。
3、抽象工厂模式
定义:提供了一个接口,用于创建相关的或依赖对象的家族,而那不需要明确指定具体类。
?????神马意思呢??????
继续拿拉面的实例来说吧,生意火拉肯定就有人会动歪脑子,使用劣质肉和面粉,想赚更多钱,这样会搞砸这个牌子的。因此我们就需要建立自己的原材料供应渠道,保证高质量的原材料供应。
于是乎呢,我们新建一个提供原材料的接口:
package com.example;
/**
* Created by leiqi on 16-5-13.
* 提供拉面的原材料
*/
public interface LaMIanYCLFactory {
/**
* 生产优质牛肉
*/
public Meat createMeat();
/**
* 生产面粉,熬汤的调料等等
*/
public YCL createYCL();
}
/**
* 根据兰州当地特色,提供这两种材料
*
*
*/
public class LZLaMIanYLFactroy implements LaMianYLFactroy
{
@Override
public Meat createMeat()
{
return new FreshMest();
}
@Override
public YuanLiao createYuanliao()
{
return new XianTeSeYuanliao();
}
}
有拉原材料供货渠道,我们稍微修改一下LaMian的prepare方法:
package com.example;
/**
* Created by leiqi on 16-5-12.
*/
public abstract class LaMian {
protected String name;
/**
* 准备工作
*/
public void prepare(LaMIanYCLFactory yclFactory)
{
Meat meat = yclFactory.createMeat();
YCL yuancailiao = yclFactory.createYCL();
System.out.print("使用官方的原料" + meat + " , " + yuancailiao + "作为原材料制作拉面 ");
}
/**
* 拉面
*/
public void Lamian ()
{
System.out.print("开始拉面工作");
}
/**
* 煮面
*/
public void ZhuMian ()
{
System.out.print("煮面工作");
}
}
好了,现在必须用我们官方原料做为原材料了。
对比定义:
1、提供一个接口:public interface LaMianYCLFactory
2、用于创建相关的或依赖对象的家族/*** 生产优质牛肉*/public Meat createMeat();/*** 生产面粉,熬汤的调料等等*/public YCL createYCL();,这里所说的依赖对象的家族就是创建一系列的原材料。
OK 至此,所有的工厂模式就简单介绍完拉!欢迎评论,留言,嘻嘻嘻嘻~~~~
作者:紫雾凌寒
来源:CSDN