Java 设计模式之静态工厂方法模式

设计模式系列

创建型设计模式

Java 设计模式之单例模式

Java 设计模式之静态工厂方法模式

Java 设计模式之工厂方法模式

Java 设计模式之抽象工厂模式

Java 设计模式之Builder模式

Java 设计模式之静态工厂、工厂方法、抽象工厂和 Builder 模式的区别

结构型设计模式

Java 设计模式之代理模式

Java 设计模式之外观模式

写在前面


先来一个迟到的祝福,祝大家中秋节快乐!应个景吧,工厂模式系列的例子和代码,将以 “月饼” 为主题进行。

工厂模式细分起来,分为三种:静态工厂方法模式、工厂方法模式、抽象工厂方法模式。本文我们先来了解最简单的静态工厂方法模式。

定义


静态工厂方法模式,又称为 简单工厂模式,属于创建型设计模式,但不属于 GOF 提出的 23 种设计模式之一。这种形式的工厂模式,是最常用,也最简单、最容易理解的工厂模式,其是由一个工厂类对象决定创建哪一种产品类的实例

示例


场景

来我们来考虑一个场景:
1、小A有一家月饼工厂,叫做 MooncakesFactory
2、月饼有 五仁月饼 FiveKernel 、豆沙月饼 Beansand
3、我们抽象出月饼的产品抽象类 Mooncakes ,拥有“吃”的行为(当然,应该是人吃月饼,而不是月饼吃自己,这里为了好理解,就将吃的行为赋给了月饼)。
4、当想要某种类型的月饼时,通过工厂类得到相应的月饼类即可进行生产

UML类图

让我来看下它们的 UML 类图吧,如图 1 :
静态工厂方法模式示例的 UML 类图

图 1    静态工厂方法模式 示例的 UML 类图

程序代码

下面我们阅读下程序代码。


程序清单 1     月饼的产品抽象类 Mooncakes
public abstract class Mooncakes{
    abstract void eat();
}

可以看到,抽象类 Mooncakes 简单的抽象了一种行为,就是吃月饼 eat()



程序清单 2     五仁月饼 实现类 FiveKernel
public class FiveKernel extends Mooncakes{

    @Override
    public void eat() {
        System.out.println("吃一个五仁月饼");
    }

}



程序清单 3     豆沙月饼 实现类 Beansand
public class Beansand extends Mooncakes{

    @Override
    public void eat() {
        System.out.println("吃一个豆沙月饼");
    }

}




下面我们来看下工厂类的代码:

程序清单 4     月饼工厂类 MooncakesFactory
public class MooncakesFactory {

    public static Mooncakes makeMooncakes(String type) {
        Mooncakes mooncakes = null;
        switch (type) {
        case "FiveKernel":
            mooncakes = new FiveKernel();
            break;
        case "Beansand":
            mooncakes = new Beansand();
            break;
        }
        return mooncakes;
    }

}

当想要某种类型的月饼时,通过工厂类得到相应的月饼类,即可开始生产。

这就通过工厂,实现了对产品类实例的管理。

那么,如果有了一种的新的月饼类型,比如蛋黄月饼,那么我们需要扩展一个新类 Yolk 继承抽象产品类 Mooncakes,同时还需要对工厂类 MooncakesFactory 进行修改,以便适应新的月饼类型(int type)。

我们知道,我们的程序应该“ 面向扩展开放,面向修改关闭 ”,我们对工厂类的修改自然是不符合" 开闭原则 " 的,让我们用反射对工厂类进行优化吧:


程序清单 5     用反射优化月饼工厂类 MooncakesFactory
public class MooncakesFactory {

    public static <T extends Mooncakes> T makeMooncakes(Class<T> clz) {
        Mooncakes mooncakes = null;
        try {
            mooncakes = (Mooncakes) Class.forName(clz.getName()).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return (T) mooncakes;
    }

}

这样,无论我们扩展多少种月饼类型,只需要将相应的月饼类注入工厂的 makeMooncakes() 方法即可,不需要再对工厂类的代码进行修改。

最后,我们在主函数中调用工厂得到月饼类的实例,即可开始生产。


程序清单 6     工厂生产产品实例  进行产品生产
public class Main {
    
    public static void main(String[] args) {

        MooncakesFactory.makeMooncakes(FiveKernel.class).eat();
        MooncakesFactory.makeMooncakes(Beansand.class).eat();

    }

}

结果示例,如图 2 :

生产月饼,吃掉月饼

图 2    生产月饼  吃掉月饼

总结


至此,静态工厂方法模式基本就聊完了。

大家会发现,这种模式十分简单,优点也是十分明显:

用户只需要关心自己想要什么类型的产品对象,而对产品对象的创建过程无须关心,全部交给工厂来做,降低了用户与产品类的耦合,也便于对产品的类型进行扩展。

然而,正如前文所说,“ 静态工厂方法模式 ” 不属于 GOF 提出的 23 种设计模式之一,“ 工厂方法模式 ” 则包含其中,让我们移步下一讲,一起学习下 Java 设计模式之工厂方法模式 吧!

另外,源码也有放在 Gihub 上:StaticFactoryPattern

感谢

  • 《Android源码设计模式解析与实战》 何红辉 关爱民
  • 《Android进阶之光》 刘望舒
  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值