Fork me on GitHub

每天学一个设计模式之开篇--简单工厂讲解

设计模式对于软件工程师的重要不言而喻,在这个专题里我将从零开始,讲解重要常见的一些设计模式。并会结合自己的经验,添加设计模式在源码及框架中的应用。如:模板设计模式在Java Thread类里的应用,装饰器模式在Netty里的应用等。这个专题将同步在简书、github以及知乎专栏、个人博客更新。好了,废话不多说,Let’s Go!希望你们能与我一起成长!

一、什么是简单工厂

首先简单工厂并不是一个真正的设计模式,即它不是GOF23种设计模式中的一种,但是和抽象工厂和工厂方法模式一样,经常被用于封装创建对象的代码。抽象工厂和工厂方法都是基于简单工厂的演进,因此学习简单工厂还是很必要的。

扩展:一共有五种创建模式:

  1. Abstract factory pattern:抽象工厂模式
  2. Builder patten:建造者模式
  3. Factory method pattern:工厂方法模式
  4. Prototype pattern:原型模式
  5. Single pattern:单例模式

    二、适用场景

    • 工厂类负责创建的对象比较少;
  • 客户端只知道传入工厂类的参数,对于如何创建对象的逻辑并不关心。
    #三、代码Coding:

    3.1 场景:一个店铺是可以生产各种各样的披萨的,各种披萨的生产工艺也是各有差异的。

    3.2 coding:

    3.2.1 定义抽象方法

    1
    2
    3
    4
    public abstract class Pizza{
    //各个pizza准备的原材料是不同的
    public abstract void prepare();
    }

3.2.2 定义芝士披萨

1
2
3
4
5
6
7
public class CheesePazza extends Piazza{
@Override
public void prepare(){
System.out.println("need prepare some cheese");
}

}

3.2.3 定义另外一种披萨:蔬菜披萨

1
2
3
4
5
6
public class ViggiePizza extends Piazza{
@Override
public void prepare(){
System.out.println("need prepare some viggie");
}
}

3.2.4 定义披萨生产店

1
2
3
4
5
6
7
8
9
10
11
12
public class PizzaShop{
//生产不同的披萨
public Pizza porduce(String type){
if(StringUtils.equals("cheese")){
return new CheesePizza();
}else if(StringUtils.equals("viggie"){
return new ViggiePizza();
}else{
return null;
}
}
}

3.2.5 客户端调用披萨生产类来生产具体的披萨 。

注意在导入包的时候是无需导入具体的CheesePizza或者ViggiePizza的

1
2
3
4
5
6
7
8
9
10
public class Client{
public static void main(String[] args){
PizzaShop pizzaShop = new PizzaShop();
pizza pizza = pizzaShop.produce("cheese");
if(pizza == null){
return;
}
System.out.println(cheesePizza.prepare());
}
}

优化:使用反射来优化披萨生产店

1
2
3
4
5
6
7
8
public class PizzaShop{
//生产不同的披萨
public Pizza porduce(Class cls){
Pizza pizza = null;
pizza =(Pizza) Class.ForName(cls.getName()).new Instance();
return pizza;
}
}

#三、简单工厂的时序图
时序图

#三、简单工厂在JDK源码中的应用

  1. 在java.util.Calendar中有这样一个方法
    getInstance方法,获取Calendar实例
    注意观察switch代码块,就是简单工厂的应用