体验一把当老总的感觉 -- 工厂模式 (诙谐的讲解)

前言:

作为一个程序员,相信你已经有所体会,计算机中的一些思想往往源于实际生活。也就是常说的艺术来源
于生活,接下来,通过一些生活中的例子来分析一下我对工厂模式的浅陋见解,如有解释的不到位的地方,
欢迎各位大佬能够指出。

你想建个什么样的工厂?

在这里,假设你是一个汽水销售工厂的老板,汽水自然有各种各样的种类:苹果味汽水、柠檬味汽水、芒
果味汽水,and so on...............
我们就通过这样的设想来建立一个获得更大利润的工厂:
想一下,现在 苹果味汽水和柠檬味汽水工厂 都是独立的,作为汽水销售工厂的老板,肯定是种类越多越
好,但是,由于各种口味的工厂都是相互独立的,所以就需要去逐个工厂进货,现在只有两个工厂的口味,
运输费还不是太多,但是有 100 种口味的呢?作为汽水销售老总的你,愿意去跑 100 家汽水口味工厂
吗?如果您愿意,那么祝您生意兴隆,嘻嘻。
正在你为运费太贵准备撒手不干时,得到小道消息,附近有个工厂生产各种汽水(假设与其他地方汽水
质量一样,嘻嘻,不要在乎小细节),作为老总的你,喜出望外,这样的话,我不是只跟这个工厂合作就行了
。其他的苹果味呀、柠檬味呀,都不用我操心啦,这样运费由原来的 100 缩减到 1 ,是不是自然会赚
大钱呢?

通过上面的例子相信你已经成为一个合格的老总啦。
简单来说,就是:

我们只跟一个工厂合作就行,而这个工厂完成之前与其他工厂合作的要求。

建造工厂:

传统方式创建:

在用工厂模式之前,我们先用普通的方法实现一下我们的需求:
需求如下:
	1、汽水的种类有很多(苹果味汽水、柠檬味汽水)。
	2、汽水的制作方式(prepare、bake、cut、box)。
	3、完成 汽水的订购功能。
作为老总,我们如何用普通的方法实现该需求呢?
	首先,每种汽水只是制作方式不同,所以建立一个 abstract Class Water(){}。
	苹果味的还是柠檬味的只需 extends Water 即可。
	各种口味只是 prepare() -- 原料不同,所以该方法设置成 abstract,其他在抽象类中实现即可
	最后订购的功能进行测试即可。

传统方式代码:
1、 abstract Class Water(){}。

package rj.factory.simpleFactory.water;

// 汽水抽象类
public abstract class Water {
    // 汽水口味的 name
    String name = null;
    // 汽水制作的原料准备,由于每种口味的原料不同,所以交给各自的子类进行实现该抽象类
    public abstract void prepare();

    public void bake() {
        System.out.println(name + "制作过程 1 。。。。。。");
    }

    public void cut() {
        System.out.println(name + "制作过程 2 。。。。。。");
    }

    public void box() {
        System.out.println(name + "制作过程 3 。。。。。。");
    }
    // 获取汽水口味的 name
    public void setName(String name) {
        this.name = name;
    }
}

2、苹果味的还是柠檬味的只需 extends Water 即可目前是两个工厂
AppleWater.java – extends Water(实现准备原料功能)

package rj.factory.simpleFactory.water;

public class AppleWater extends Water{
    @Override
    public void prepare() {
        System.out.println(name + "汽水原料正在准备中!!!");
    }
}

OrangeWater.java – extends Water(实现准备原料功能)

package rj.factory.simpleFactory.water;

public class OrangeWater extends Water{
    @Override
    public void prepare() {
        System.out.println(name + "汽水原料正在准备中!!!");
    }
}

orderWater.java – 老总开始订购不同的口味:


package rj.factory.simpleFactory.order;

import rj.factory.simpleFactory.water.AppleWater;
import rj.factory.simpleFactory.water.OrangeWater;
import rj.factory.simpleFactory.water.Water;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderWater {
    // 获取控制台的输入
    String  orderType = null;
    // 根据不同的需求产生不同的对象
    Water water = null;
    public OrderWater() throws IOException {
        do{
        	// 订购不同的口味都需要亲自跑一趟,工厂模式主要在这里优化
            orderType = getType();
            if(orderType.equals("apple")) {
                water = new AppleWater();
            } else if(orderType.equals("orange")) {
                water = new OrangeWater();
            } else {
                break;
            }
            // 执行产品的各个流程
            water.setName(orderType);
            water.prepare();
            water.bake();
            water.cut();
            water.box();
        } while(true);
    }

    // 通过控制台进行输入不同的口味
    public String getType() throws IOException {
        BufferedReader strain = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("input water type:");
        String str = strain.readLine();
        return str;
    }
}

Test.java

import org.junit.Test;
import rj.factory.simpleFactory.order.OrderPizza;
import rj.factory.simpleFactory.order.OrderWater;
import rj.factory.simpleFactory.order.SimpleFactory;

import java.io.IOException;

public class FactoryTest {
	// 老总的工厂
    public static void main(String[] args) throws IOException {
        new OrderWater();
    }
}

简单工厂模式创建:

想一下我们最初的举例,类比一下,就是如果有 100 种口味的产品,我们就需要在下面这个地方创建 
100 个对象:

这里只是一个店需要的,如果你以后做大做强了,有100家分店,在每家分店都需要创建 100个对象,这是不是就有点麻烦啦。如果我们在这个地方交给一个工厂,每家店和 1 个工厂对接还是跟 100 个工厂对接,当然是跟 1 个工厂对接方便啦(理解这点很重要)。
在这里插入图片描述
在这个地方用 简单工厂模式 优化:
首先要有一个让老总喜出望外的总工厂:

package rj.factory.simpleFactory.order;

import rj.factory.simpleFactory.water.AppleWater;
import rj.factory.simpleFactory.water.OrangeWater;
import rj.factory.simpleFactory.water.Water;

// 简单工厂
public class WaterFactory {

    // 根据不同的需要 new 不同的对象(这些都由工厂实现,老总不需要知道为什么)
    // 也就是说不用老总一个一个跑腿啦,(不在需要手动一直 new 了)
    public Water createFactory(String orderType) {
        Water water = null;
        if(orderType.equals("apple")) {
            water = new AppleWater();
        } else if(orderType.equals("orange")) {
            water = new OrangeWater();
        }
        return water;
    }

}

可以开开心心的和大工厂合作啦,再也不用担心运费啦

package rj.factory.simpleFactory.order;

import rj.factory.simpleFactory.water.AppleWater;
import rj.factory.simpleFactory.water.OrangeWater;
import rj.factory.simpleFactory.water.Water;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class OrderWater {
    // 获取控制台的输入
    String  orderType = null;
    // 根据不同的需求产生不同的对象
    Water water = null;
    // 汽水工厂总厂(让老总喜出望外的地方)
    WaterFactory waterFactory = null;
    public void setWaterFactory(WaterFactory waterFactory) {
        this.waterFactory = waterFactory;
    }
    public OrderWater(WaterFactory waterFactory) throws IOException {

        do{
            orderType = getType();
            // 向工厂传递类型,又大工厂进行 new (寻找小工厂进行生产,老总不用管啦)
            // 主要是在这里优化
            water = waterFactory.createFactory(orderType);
            if(water != null) {
                water.setName(orderType);
                water.prepare();
                water.bake();
                water.cut();
                water.box();
            } else {
                System.out.println("Sorry,暂时没有您想要的口味。。。。");
                break;
            }
        } while(true);

    }

    // 通过控制台进行输入不同的口味
    public String getType() throws IOException {
        BufferedReader strain = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("input water type:");
        String str = strain.readLine();
        return str;
    }

}

Test.java:

import org.junit.Test;
import rj.factory.simpleFactory.order.OrderPizza;
import rj.factory.simpleFactory.order.OrderWater;
import rj.factory.simpleFactory.order.SimpleFactory;
import rj.factory.simpleFactory.order.WaterFactory;

import java.io.IOException;

public class FactoryTest {

    public static void main(String[] args) throws IOException {
        // 肯定需要一个工厂(只不过由原来的多个工厂成了只和一个工厂进行合作)
        new OrderWater(new WaterFactory());
    }
}

赚钱啦!

你可能会有疑问:这个并没有简化多少呀,在 WaterFactory 中要有新口味的汽水增加的话不是还需要
手动 new 吗? 是的,但是如果有 100 个老总呢?成千上万个呢?这时候如果采用传统的方法,每个
老总的场子都需要 new 100 个,用 WaterFactory 后,只需要导个包就 OK 啦,是不是工厂模式就更
适用啦。

后记:

嘻嘻,废话说了这么多,实际上就是大佬们常说的 解耦 ,也就是降低耦合性,更利于我们的维护,因为
我们维护系统的最好少修改原先的代码,就像你正在开黑,这时停电啦(可能有点不恰当,嘻嘻,但是还
比较好理解的)。
后面还有 工厂方法模式和工厂抽象模式,实际上都是在简单工厂模式上的进一步深化,之后会补上。
如果本篇文章对你有帮助,不要忘记点个赞哦 ^_^!
加油!

猜你喜欢

转载自blog.csdn.net/qq_43619271/article/details/106200105