[Android设计模式之旅]————工厂模式

棉花糖
发布于 2020-9-24 10:30
浏览
0收藏

设计模式(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

分类
收藏
回复
举报
回复
    相关推荐