嘻哈说:设计模式之工厂方法模式

一、嘻哈说

这首歌还没写不能发java

由于本节的工厂方法模式与抽象工厂模式存在关联度,因此会在下一节《抽象工厂模式》中混成一首歌发。设计模式

二、简单工厂模式的定义

现实中的工厂,是用来生产产品的,而代码中的工厂,则是建立对象的,bash

用来建立对象,那确定就是建立型模式了。ide

咱们常常会用到三种和工厂相关的设计模式:简单工厂模式、工厂方法模式、抽象工厂模式。学习

这节我们要说的是——工厂方法模式。ui

不过,再说工厂方法以前,咱们要先说下简单工厂模式。咱们从简单的开始入手,由简入繁。spa

简单工厂模式呢,它不属于Gof23种设计模式之一,但它在实际的项目中常常被用到,因此咱们仍是颇有必要学习,而且它的思想也很是简单,能够说是工厂方法模式的一个引导。设计

咱们来看一下简单工厂方法的定义。code

又称为静态工厂模式,由一个工厂对象决定建立出哪种产品类的实例。cdn

注意这里的定义,是一个工厂对象

怎么实现呢?实现的套路是什么?

定义一个工厂类,能够根据参数的不一样返回不一样类的实例,被建立的实例一般有共同的父类。

三、场景

场景与建造者模式有点相似,仍是熟悉的饺子,仍是熟悉的配方,仍是熟悉的味道,扯远了...

美食饺子

番茄餐厅的后厨。

厨师长:老板,我据说隔壁餐厅买来了一个机器,包饺子神器,一输入参数,饺子直接出锅,高科技呀,跟饺子工厂似的。

老板:你的意思是我们也去买个?

厨师长:嗯,我是想提这个建议的,一键出饺子,想一想内心还有点小激动呢。

老板:你不会是为了图省事吧?

求生欲极强的厨师长:固然不是,我是以为饺子神器效率高,可以给咱们饭店带来更大的价值。

老板:嗯,那我赞成了,钱从你工资里扣。

委屈的厨师长:老板,这样不合适吧?我上有老,下有...

老板:打住,逗你的,看把你给吓得。效率提升但味道下降,这种神器我们饭店不会用的。

咱们今天的例子,就是饺子工厂,能够生产各类饺子馅、皮。

四、简单工厂模式

简单工厂UML图

简单工厂模式的UML类图。

package com.fanqiekt.factory.simple;

/**
 * 饺子馅
 *
 * @Author: 番茄课堂-懒人
 */
public interface IStuffing {

    void make();

}
复制代码

IStuffing:产品(饺子馅)的接口,共有的父类。

make()就是制造饺子皮的方法。

package com.fanqiekt.factory.simple;

/**
 * 猪肉大葱馅
 * @Author: 番茄课堂-懒人
 */
public class PorkStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("制做猪肉大葱馅");
    }

}
复制代码
package com.fanqiekt.factory.simple;

/**
 * 茴香鸡蛋馅
 * @Author: 番茄课堂-懒人
 */
public class FoeniculumVulgareStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("制做茴香鸡蛋馅");
    }

}
复制代码
package com.fanqiekt.factory.simple;

/**
 * 韭菜鸡蛋馅
 * @Author: 番茄课堂-懒人
 */
public class ChineseChivesStuffing implements IStuffing {

    @Override
    public void make() {
        System.out.println("制做韭菜鸡蛋馅");
    }

}
复制代码

具体的产品类,饺子馅中的大户:猪肉大葱馅、茴香鸡蛋馅、韭菜鸡蛋馅。

package com.fanqiekt.factory.simple;

/**
 * 饺子馅工厂类
 * @Author: 番茄课堂-懒人
 */
public class StuffingFactory {
    public static IStuffing getStuffing(String key){
        IStuffing stuffing = null;
        switch (key){
            case "猪肉大葱":
                stuffing = new PorkStuffing();
                break;
            case "韭菜鸡蛋":
                stuffing = new ChineseChivesStuffing();
                break;
            case "茴香鸡蛋":
                stuffing = new FoeniculumVulgareStuffing();
                break;
        }
        return stuffing;
    }
}
复制代码

StuffingFactory:饺子馅工厂类。

简单工厂中只有一个工厂类,而且提供了一个静态公有方法,能够根据参数的不一样返回不一样类的实例。

这也是简单方法为何要被称之为静态工厂模式的缘由。

package com.fanqiekt.factory.simple;

/**
 * 客户端
 * @Author: 番茄课堂-懒人
 */
public class Client {

    public static void main(String args[]){
        IStuffing stuffing = StuffingFactory.getStuffing("猪肉大葱");
        stuffing.make();

        System.out.println("------------");

        stuffing = StuffingFactory.getStuffing("韭菜鸡蛋");
        stuffing.make();

        System.out.println("------------");

        stuffing = StuffingFactory.getStuffing("茴香鸡蛋");
        stuffing.make();
    }

}
复制代码

客户端类。

咱们能够看出,简单工厂不愧为简单工厂,就是赤裸裸的简单。

但简单并不普通,它完美的展示了工厂方法的思想,让工厂建立对象,而不是对象A去建立对象B。

这样能够避免对象A与对象B之间的耦合。

咱们运行一下,看结果。

制做猪肉大葱馅
------------
制做韭菜鸡蛋馅
------------
制做茴香鸡蛋馅
复制代码

五、工厂方法模式的定义

若是按照简单工厂的写法,在不使用java的反射的前提下,扩展性是不好的。

若是添加一种饺子馅,必须修改工厂中的判断。

因此咱们来介绍一下另一种工厂模式——工厂方法模式,下面,咱们有请男主出场。

咱们先来看看,工厂方法模式的官方定义:

定义一个用于建立对象的接口,让子类决定实例化哪个类。

从定义中,咱们能够看出实现的套路:定一个建立对象的接口,而后每一个工厂去实现该接口实例化特定的对象,这样就使一个类的实例化延迟到其子类。

每个产品都有相应的工厂,这就是与简单工厂模式最大的区别。

而后,调用者能够自由的 选择使用哪一个工厂去建立对象。

六、工厂方法模式

工厂方法UML图

工厂方法模式的UML类图。

产品(饺子馅)与简单工厂模式的代码一致,这里就不贴出来了。

package com.fanqiekt.factory.method;

/**
 * 工厂接口
 * @Author: 番茄课堂-懒人
 */
public interface IFactory {

    IStuffing getStuffing();

}
复制代码

IFactory:工厂的接口。

定义一个用于建立对象的接口。

getStuffing()得到产品(饺子馅)的方法,交给具体的子类来实现。使一个类的实例化延迟到其子类。

package com.fanqiekt.factory.method;

/**
 * 猪肉大葱馅工厂
 * @Author: 番茄课堂-懒人
 */
public class PorkFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new PorkStuffing();
    }
}
复制代码
package com.fanqiekt.factory.method;

/**
 * 茴香鸡蛋馅工厂
 * @Author: 番茄课堂-懒人
 */
public class FoeniculumVulgareFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new FoeniculumVulgareStuffing();
    }
}
复制代码
package com.fanqiekt.factory.method;

/**
 * 韭菜鸡蛋馅工厂
 * @Author: 番茄课堂-懒人
 */
public class ChineseChivesFactory implements IFactory {
    @Override
    public IStuffing getStuffing() {
        return new ChineseChivesStuffing();
    }
}
复制代码

具体的工厂类。

为每一个产品(饺子馅)提供一个工厂类:猪肉大葱馅工厂、茴香鸡蛋馅工厂、韭菜鸡蛋馅工厂。

这样的设计,扩展起来也很是的方便,例如增长三鲜馅,只须要增长产品类(三鲜馅)、工厂类(三鲜馅)就能够了。不会影响其余。

七、区别

简单工厂模式,只有一个工厂类,根据参数的不一样返回不一样类的实例。

工厂方法模式,定义一个建立对象的接口,存在实现该接口的多个工厂类。调用者选择使用哪一个工厂。

八、END

从下一节课程开始,《嘻哈说——设计模式》系列的课程将不在其余渠道发布,改成公众号《番茄课堂》独家发布,期待你们的关注。

今天就先说到这里,下一节说《抽象工厂模式》,感谢你们支持。

相关文章
相关标签/搜索